Ruby 使用<=&燃气轮机;而不仅仅是排序和反转?
这样做有什么好处(如果有的话):Ruby 使用<=&燃气轮机;而不仅仅是排序和反转?,ruby,Ruby,这样做有什么好处(如果有的话): books.sort!{|第一本书,第二本书|第二本书第一本书} 与: books.sort!。倒车 第二种选择似乎更清晰、更容易理解 编辑:我想这可能是一个问题,除了1对1排序之外,运算符还有什么其他用途?我对性能问题的最初回答被证明主要基于一个错误的假设:排序中没有固有的性能影响,由于无块的排序似乎比有块的排序更快,因此它抵消了第二次反向调用的成本,这一成本可以忽略不计 但是,我的答案的要点仍然有效:您应该选择第二行,因为它更可读,并且在确定性能问题时,您应
books.sort!{|第一本书,第二本书|第二本书第一本书}
与:
books.sort!。倒车代码>
第二种选择似乎更清晰、更容易理解
编辑:我想这可能是一个问题,除了1对1排序之外,运算符还有什么其他用途?我对性能问题的最初回答被证明主要基于一个错误的假设:排序中没有固有的性能影响,由于无块的排序
似乎比有块的排序
更快,因此它抵消了第二次反向调用的成本,这一成本可以忽略不计
但是,我的答案的要点仍然有效:您应该选择第二行,因为它更可读,并且在确定性能问题时,您应该担心找出哪一行更快
原答覆如下:
第二种选择更昂贵。它按升序对所有内容进行排序,然后反转数组,这是两个不同的过程,而第一个选项立即按降序生成数组
也就是说,第二种选择是我更喜欢的。通常,我们更喜欢生成可读、可维护的代码,而不是过早地优化性能
显然,你必须问自己:“这段代码每秒运行很多次吗?”或者“这段代码在应用程序的生命周期中运行一次吗?”你的优先级会相应地改变,但一般来说,可维护性胜过性能
使用第二个选项,直到您能够证明这是一个性能瓶颈。我非常惊讶,但第二个选项似乎更快,而且不仅仅是一点点
require 'benchmark'
array = (1..10**7).to_a.shuffle
Benchmark.bm do |x|
x.report { array.sort { |firstBook, secondBook| secondBook <=> firstBook }}
x.report { array.sort.reverse }
end
我的猜测是,int的排序完全是通过内部c函数完成的,而带有块的int需要不断调用ruby解释器。我本来希望这样做,因为sort\u by
需要块调用,而sort
直接调用c方法,而reverse是便宜的操作。@meager-不是,我已更改排序
进入排序
,我也检查了数组。首先
在所有测试运行之后-它是一个随机数,既不是1
也不是10**7
。有趣的是,在ruby 1.9.3中,第一个只慢了约7倍,而在1.8中则慢了约110倍。@BroiSatse啊,没错。有趣的是,它看起来像是.sort.reverse
总是比调用.sort{a,b | ba}
更快,即使对于复杂类型也是如此。我假设没有参数的.sort
被优化为遍历数组并以本机方式调用
,而带有块的.sort
必须在Ruby中调用
。事实是,相反代码>是O(n)
,与排序相比可以忽略不计
,因此“更昂贵”并不十分准确,尤其是调用块的需要非常昂贵,使得第一个选项最终的性能大大降低。考虑到@Broi的实验,我将最后一行改为“使用第二个选项”。@AShelly这仍然很难被证明是性能瓶颈。仅仅因为它在10^7记录的合成基准测试中运行较慢,并不意味着它在实际应用程序中被证明是性能瓶颈。如果在应用程序的生命周期中执行一次,输入20条记录,则性能不会有可测量的差异。
user system total real
21.090000 0.030000 21.120000 ( 21.135562)
2.060000 0.020000 2.080000 ( 2.098318)