集合的性能V.S. Ruby中的数组

时间:2012-08-16 16:43:11

标签: ruby

在Ruby中,我正在构建一个构造并返回一个(可能很大)数组的方法,该数组不应包含任何重复元素。通过使用一个集合然后将其转换为数组,我会获得更好的性能吗?或者,在我返回之前,在我正在使用的数组上调用.uniq会更好吗?或者使用&将项目附加到数组而不是+=呢?如果我确实使用了一个集合,那么在我放入集合的对象上没有<=>方法会对性能产生影响吗? (如果你不确定,你知道一种测试方法吗?)

2 个答案:

答案 0 :(得分:5)

真正的答案是:编写最具可读性和可维护性的代码,并在您显示它是瓶颈后才对其进行优化。如果您可以在is in linear time中找到算法,则无需对其进行优化。在这里很容易找到......

不太确定您建议使用哪种方法,但使用我的fruity gem:

require 'fruity'
require 'set'

enum = 1000.times

compare do
  uniq { enum.each_with_object([]){|x, array| array << x}.uniq }
  set  { enum.each_with_object(Set[]){|x, set| set << x}.to_a }
  join { enum.inject([]){|array, x| array | [x]} }
end

# set is faster than uniq by 10.0% ± 1.0%
# uniq is faster than join by 394x ± 10.0

显然,像第三种方法一样构建中间数组是没有意义的。否则,它将不会产生很大的不同,因为你将在O(n);这是主要的事情。

顺便说一句,setsuniqArray#|对您的对象使用eql?hash,而不是<=>。这些需要以理智的方式定义,因为默认情况下,对象永远不会eql?,除非它们具有相同的object_id(请参阅this question

答案 1 :(得分:3)

您是否尝试过使用Benchmark库?测试通常很容易构建,并且能够正确反映它在特定版本的Ruby中的工作方式。