我有以下情况。我有一大堆随机字符串。应尽快使该数组变得唯一。
现在通过一些基准测试我发现 ruby 的 uniq 相当慢:
require 'digest'
require 'benchmark'
#make a nice random array of strings
list = (1..100000).to_a.map(&:to_s).map {|e| Digest::SHA256.hexdigest(e)}
list += list
list.shuffle
def hash_uniq(a)
a_hash = {}
a.each do |v|
a_hash[v] = nil
end
a_hash.keys
end
Benchmark.bm do |x|
x.report(:uniq) { 100.times { list.uniq} }
x.report(:hash_uniq) { 100.times { hash_uniq(list) } }
end
要点->https://gist.github.com/stillhart/20aa9a1b2eeb0cff4cf5 https://gist.github.com/stillhart/20aa9a1b2eeb0cff4cf5
结果非常有趣。难道是ruby的uniq很慢吗?
user system total real
uniq 23.750000 0.040000 23.790000 ( 23.823770)
hash_uniq 18.560000 0.020000 18.580000 ( 18.591803)
现在我的问题是:
有没有更快的方法可以使数组变得唯一?
难道我做错了什么?
Array.uniq 方法有问题吗?
我正在使用 ruby 2.2.3p173 (2015-08-18 修订版 51636) [x86_64-linux]
对大型数据集的字符串解析操作当然不是 Ruby 的亮点。如果这对业务至关重要,您可能需要用 C 或 C 等语言编写扩展Go http://dev.mikamai.com/post/130986121064/writing-ruby-extensions-in-go-an-in-depth-review,或者让另一个应用程序在将其传递给您的 Ruby 应用程序之前处理它。
就是这样说的。您的基准似乎有些奇怪。使用 Ruby 在我的 MacBook Pro 上运行相同的代码2.2.3
呈现以下结果:
user system total real
uniq 10.300000 0.110000 10.410000 ( 10.412513)
hash_uniq 11.660000 0.210000 11.870000 ( 11.901917)
建议uniq
稍微快一些。
如果可能,您应该始终尝试使用正确的集合类型。如果您的收藏确实独一无二,那么请使用Set http://ruby-doc.org/stdlib-2.2.3/libdoc/set/rdoc/Set.html。它们具有更好的内存配置文件和更快的查找速度Hash
,同时保留一些Array
直觉。
如果您的数据已经存在于Array
,但是,这可能不是一个好的权衡,因为插入Set
也相当慢,正如您在这里看到的:
user system total real
uniq 11.040000 0.060000 11.100000 ( 11.102644)
hash_uniq 12.070000 0.230000 12.300000 ( 12.319356)
set_insertion 12.090000 0.200000 12.290000 ( 12.294562)
我在其中添加了以下基准:
x.report(:set_insertion) { 100.times { Set.new(list) } }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)