排序哈希的最快方法是什么?

the*_*Man 3 ruby

人们经常会问什么是对哈希进行排序的最佳方法,但是他们并没有问到所需的后续问题是什么是最快的方法,这确实是最好的方法.

无论使用何种Ruby版本,在Ruby中对Hash进行排序的最快方法是什么?

我正在寻找能够涵盖极端情况的其他答案,或者发现更通用和/或最快的方法的问题.

the*_*Man 6

排序哈希的最快方法是什么?

require 'fruity'

HASH = Hash[('a'..'z').to_a.shuffle.map{ |k| [k, 1] }]

def sort_hash1(h)
  h.sort.to_h
end

def sort_hash2(h)
  Hash[h.sort]
end

def sort_hash3(h)
  Hash[h.sort_by{ |k, v| k }]
end

def sort_keys(h)
  keys = h.keys.sort
  Hash[keys.zip(h.values_at(*keys))]
end

puts "Running on Ruby v#{ RUBY_VERSION }"
puts

compare do
  do_sort_hash1 { sort_hash1(HASH) } if [].respond_to?(:to_h)
  do_sort_hash2 { sort_hash2(HASH) }
  do_sort_hash3 { sort_hash3(HASH) }
  do_sort_keys { sort_keys(HASH) }
end
Run Code Online (Sandbox Code Playgroud)

在Mac OS便携式计算机上运行上述代码会产生以下输出:

# >> Running on Ruby v2.2.2
# >> 
# >> Running each test 256 times. Test will take about 1 second.
# >> do_sort_keys is faster than do_sort_hash3 by 39.99999999999999% ± 10.0%
# >> do_sort_hash3 is faster than do_sort_hash1 by 1.9x ± 0.1
# >> do_sort_hash1 is similar to do_sort_hash2
Run Code Online (Sandbox Code Playgroud)

和:

# >> Running on Ruby v1.9.3
# >> 
# >> Running each test 256 times. Test will take about 1 second.
# >> do_sort_keys is faster than do_sort_hash3 by 19.999999999999996% ± 10.0%
# >> do_sort_hash3 is faster than do_sort_hash2 by 4x ± 0.1
Run Code Online (Sandbox Code Playgroud)

加倍哈希大小:

HASH = Hash[[*('a'..'z'), *('A'..'Z')].shuffle.map{ |k| [k, 1] }]
Run Code Online (Sandbox Code Playgroud)

结果是:

# >> Running on Ruby v2.2.2
# >> 
# >> Running each test 128 times. Test will take about 1 second.
# >> do_sort_keys is faster than do_sort_hash3 by 50.0% ± 10.0%
# >> do_sort_hash3 is faster than do_sort_hash1 by 2.2x ± 0.1
# >> do_sort_hash1 is similar to do_sort_hash2
Run Code Online (Sandbox Code Playgroud)

和:

# >> Running on Ruby v1.9.3
# >> 
# >> Running each test 128 times. Test will take about 1 second.
# >> do_sort_keys is faster than do_sort_hash3 by 30.000000000000004% ± 10.0%
# >> do_sort_hash3 is faster than do_sort_hash2 by 4x ± 0.1
Run Code Online (Sandbox Code Playgroud)

值将根据硬件而变化,但相对结果不应更改.

为简单起见,选择Fruity而不是使用内置的Benchmark类.

这是由" 按键排序哈希,在Ruby中返回哈希 "提示的.

  • 这是非常有趣的。它是否不建议基于`sort_keys`的方法`Hash.sort`的参数,不是因为将排序数组转换为哈希(相对较小)所需的时间,而是因为只需要按键排序,而不是按 2 元素数组排序,这就是 [Enumerable#sort](http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-sort) 所做的(即,这对于散列来说是不必要的,因为关系不会被值打破)? (2认同)