2

次の2つのルビーコードを検討してください

例1

name = user.first_name
round_number = rounds.count
users.each do |u|
  puts "#{name} beat #{u.first_name} in round #{round_number}"
end

例2

users.each do |u|
  puts "#{user.first_name} beat #{u.first_name} in #{rounds.count}"
end

両方のコードについて想像してみてください

#user.rb
def first_name
  name.split.first
end

したがって、アルゴリズムの古典的な分析では、最初のコードがより効率的ですが、ほとんどの最新のコンパイル言語では、最新のコンパイラは2番目のコードを最適化して最初のコードのように見せ、そのようなコードを最適化する必要をなくします。マナー。

rubyは、実行前にこのコードの値を最適化またはキャッシュしますか?私のルビーコードは例1または例2のように見えるべきですか?

4

2 に答える 2

2

コンパイラは、メソッドに副作用がないことを証明できる場合にのみ、この最適化を実行できます。これは、Rubyではほとんどの言語よりもさらに困難です。すべてが変更可能であり、実行時にオーバーライドできるためです。それが起こるかどうかは実装に依存しますが、Rubyで行うのは難しいため、ほとんどの場合はそうではありません。私は実際にこの投稿の時点で何をしているのか知りません。

于 2012-12-30T22:28:02.033 に答える
2

例1は、first_name()一度だけ呼び出されるため、より高速に実行され、その値は変数に格納されます。

each()例2では、​​ループの反復間で値が変更された可能性があるため、Rubyはこの値を自動的にメモ化しません。

そのため、戻り値を変更せずに複数回使用することが予想される場合は、計算にコストのかかるメソッドを明示的にメモ化する必要があります。

Rubyのベンチマークモジュールを利用すると、このような決定を下すときに役立ちます。に値がたくさんある場合users、またはfirst_name()計算にコストがかかる場合にのみ、メモ化する価値があります。

于 2012-12-30T22:18:52.910 に答える