首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Ruby中对字符串数组进行排序

在Ruby中对字符串数组进行排序
EN

Stack Overflow用户
提问于 2013-05-20 02:12:09
回答 4查看 27.4K关注 0票数 25

我在Ruby中学习了两种数组排序方法:

代码语言:javascript
复制
array = ["one", "two", "three"]
array.sort.reverse!

或者:

代码语言:javascript
复制
array = ["one", "two", "three"]
array.sort { |x,y| y<=>x }

我不能区分这两者。哪种方法更好,它们在执行过程中到底有什么不同?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-05-20 02:33:20

这两行执行相同的操作(创建一个新数组,该数组是反向排序的)。主要的争论是关于可读性和性能。array.sort.reverse!array.sort{|x,y| y<=>x}更具可读性--我想我们可以同意这一点。

对于性能部分,我创建了一个快速基准测试脚本,它在我的系统上提供了以下内容(ruby 1.9.3p392 [x86_64-linux]):

代码语言:javascript
复制
                              user     system      total        real
array.sort.reverse        1.330000   0.000000   1.330000 (  1.334667)
array.sort.reverse!       1.200000   0.000000   1.200000 (  1.198232)
array.sort!.reverse!      1.200000   0.000000   1.200000 (  1.199296)
array.sort{|x,y| y<=>x}   5.220000   0.000000   5.220000 (  5.239487)

对于基准测试脚本的多次执行,运行时间非常恒定。

array.sort.reverse (有没有!)比array.sort{|x,y| y<=>x}快得多。因此,我建议这样做。

下面是作为参考的脚本:

代码语言:javascript
复制
#!/usr/bin/env ruby
require 'benchmark'

Benchmark.bm do|b|
  master = (1..1_000_000).map(&:to_s).shuffle
  a = master.dup
  b.report("array.sort.reverse      ") do
    a.sort.reverse
  end

  a = master.dup
  b.report("array.sort.reverse!     ") do
    a.sort.reverse!
  end

  a = master.dup
  b.report("array.sort!.reverse!    ") do
    a.sort!.reverse!
  end

  a = master.dup
  b.report("array.sort{|x,y| y<=>x} ") do
    a.sort{|x,y| y<=>x}
  end
end
票数 33
EN

Stack Overflow用户

发布于 2013-05-20 02:53:11

倒车!速度更快

基准测试通常是无法替代的。虽然它在较短的脚本中可能没有区别,但#reverse!方法比使用“太空船”操作符进行排序要快得多。例如,在MRI Ruby 2.0上,并给出了以下基准代码:

代码语言:javascript
复制
require 'benchmark'

array = ["one", "two", "three"]
loops = 1_000_000

Benchmark.bmbm do |bm|
    bm.report('reverse!')  { loops.times {array.sort.reverse!} }
    bm.report('spaceship') { loops.times {array.sort {|x,y| y<=>x} }}
end

系统会报告#reverse!几乎是使用组合比较运算符的两倍。

代码语言:javascript
复制
                user     system      total        real
reverse!    0.340000   0.000000   0.340000 (  0.344198)
spaceship   0.590000   0.010000   0.600000 (  0.595747)

我的建议是:在给定的上下文中使用语义上更有意义的代码,除非您正在紧凑的循环中运行。

票数 3
EN

Stack Overflow用户

发布于 2013-05-20 02:25:24

与您的示例一样简单的比较,没有太大的区别,但由于比较公式变得复杂,最好避免将<=>与块一起使用,因为您传递的块将针对数组的每个元素进行计算,从而导致冗余。请考虑以下内容:

代码语言:javascript
复制
array.sort{|x, y| some_expensive_method(x) <=> some_expensive_method(y)}

在这种情况下,将针对array每个可能的元素对评估some_expensive_method

在您的特定情况下,可以使用reverse来避免在<=>中使用块。

代码语言:javascript
复制
array.sort_by{|x| some_expensive_method(x)}.reverse

这就是Schwartzian变换。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16637869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档