1

私はハッシュテーブルを持っています:

hash = Hash.new(0)

hash[:key] = hash[:key] + 1   # Line 1
hash[:key] += 1               # Line 2

ライン 1 とライン 2 は同じことを行います。行 1 ではキーによるハッシュを 2 回クエリする必要があるのに対し、行 2 では 1 回だけクエリを実行する必要があるようです。本当?それとも実際には同じですか?

4

4 に答える 4

4

ベンチマーク用の Ruby スクリプトを作成しました

require 'benchmark'

def my_case1()
  @hash[:key] = @hash[:key] + 1 
end

def my_case2()
  @hash[:key] += 1   
end

n = 10000000
Benchmark.bm do |test|
  test.report("case 1") { 
    @hash = Hash.new(1)
    @hash[:key] = 0
    n.times do; my_case1(); end 
  }

  test.report("case 2") {
    @hash = Hash.new(1)
    @hash[:key] = 0
    n.times do; my_case2(); end 
 }
end

これが結果です

       user     system      total        real
case 1  3.620000   0.080000   3.700000 (  4.253319)
case 2  3.560000   0.080000   3.640000 (  4.178699)

見た目hash[:key] += 1は少し良くなりました。

于 2013-08-22T03:24:49.843 に答える
1

Ruby 言語仕様では、省略されたインデックス割り当て式を評価するためのアルゴリズムが非常に明確に説明されています。それは次のようなものです:

primary_expression[indexing_argument_list] ω= expression
# ω can be any operator, in this example, it is +

(大まかに)次のように評価されます

o = primary_expression
*l = indexing_argument_list
v = o.[](*l)
w = expression
l << (v ω w)
o.[]=(*l)

特に、getter と setter の両方が 1 回だけ呼び出されていることがわかります。

また、非公式の脱糖を見てもわかります。

hash[:key] += 1

# is syntactic sugar for 

hash[:key] = hash[:key] + 1

# which is syntactic sugar for 

hash.[]=(:key, hash.[](:key).+(1))

ここでも、setter と getter の両方が 1 回だけ呼び出されていることがわかります。

于 2013-08-22T09:16:28.830 に答える
0

2 つ目は、通常の方法です。より効率的です。

于 2013-08-22T03:13:44.693 に答える