文字和构造函数之间的差异?([] vs Array.new和{} vs Hash.new)

Pri*_*ain 21 ruby ruby-on-rails

我很想知道[]和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)
Run Code Online (Sandbox Code Playgroud)

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

任何其他指针它们之间有什么区别?场景背后发生了什么使它变得如此之好,并建议何时使用哪个?

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

干杯.

Rob*_*t K 27

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


小智 6

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

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

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


knu*_*nut 6

罗伯特已经提到了默认值Hash.new

您还可以将完整的“默认”值与以下块变体一起使用Hash.new

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

p x      #-> {}
p x[1]   #-> 2
p x      #-> {1=>2}
Run Code Online (Sandbox Code Playgroud)

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

p Array.new(5, :a)  #-> [:a, :a, :a, :a, :a]
Run Code Online (Sandbox Code Playgroud)