22

我很想知道 [] 和 Array.new 以及 {} 和 Hash.new 之间的更多区别

我对其进行了相同的基准测试,似乎速记是赢家

require 'benchmark'

many = 500000

Benchmark.bm do |b|
  b.report("[]          \t") {many.times { [].object_id }}
  b.report("Array.new   \t") { many.times { Array.new.object_id }}
  b.report("{}          \t") {many.times { {}.object_id }}
  b.report("Hash.new\t") { many.times { Hash.new.object_id }}
end


                  user     system      total        real
[]            0.080000   0.000000   0.080000 (  0.079287)
Array.new     0.180000   0.000000   0.180000 (  0.177105)
{}            0.080000   0.000000   0.080000 (  0.079467)
Hash.new      0.260000   0.000000   0.260000 (  0.264796)

我个人喜欢使用简写的 [] 和 {} ,代码看起来很酷且可读。

任何其他指针它们之间有什么区别?幕后发生了什么使它变得更好,以及何时使用哪个建议?

我找到了这个链接,但希望获得更多信息。

干杯。

4

3 回答 3

30

使用 Hash.new,您可以为未设置的键设置哈希的默认值。如果您要进行统计,这非常有用,因为它Hash.new(0)可以让您在不显式初始化键的情况下增加键。

于 2012-08-03T19:23:49.813 回答
6

因此,他们都“非常快”地跑了 50 万次。我更喜欢任何语言的文字([]、{}、0、“”等),但文字不能做所有事情(请参阅其他构造函数形式的文档)。编写干净的代码,并保持一致:这里没有问题 :)

但是,怀疑文字避免了不断的查找和方法调用,这导致它们更快,至少在那个特定的实现中......(比我更聪明的人可以查看生成的中间 AST 来证明/反驳这一点。)

也就是说,如果Hash解析为自定义类Hash.new替换为自定义方法怎么办?不能这样做{}。此外,方法必须处理额外的参数(或块),而文字则不需要。

于 2012-08-03T19:19:10.163 回答
6

Robert 已经提到Hash.new

您还可以将 compley 'default'-values 与以下块变体一起使用Hash.new

x = Hash.new { |hash, key|
  hash[key] = key * 2
}

p x      #-> {}
p x[1]   #-> 2
p x      #-> {1=>2}

Array.new也可用于获取默认值:

p Array.new(5, :a)  #-> [:a, :a, :a, :a, :a]
于 2012-08-03T19:34:53.593 回答