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 に答える