5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ダブルクオートとシングルクオートの速度差は(ほぼ)ない

Last updated at Posted at 2015-09-13

Perlでは、パフォーマンスを重視するなら、シングルクオートを使うことが通説らしい(5.8時点。最近は知らない)。
それ以来、シングルクオートが文字列になる言語では基本的にシングルクオートを使うようにしている。
が、こんな記事を見つけてしまった。

Rubyのシングルクォートとダブルクォートは、実行速度には差が無い : /var/log/maeda.log
http://vividtone.seesaa.net/article/84396945.html

ダブルクオートの式展開はコンパイル時に解決されるらしい。
これを実際に検証したブログはないようだったので、検証してみた(Ruby 2.0 on OSX 10.10)。
irb上でRubyVM::InstructionSequence.compile(...).to_aを使うとバイトコードを表示できるので、これを読めば良いということになる。

検証に使う文字列はこれにした。

%q(x=5;puts "aaa #{x**3}")

irbに読ませると"x=5;puts \"aaa \#{x**3}\""となり、展開はされていないことがわかる。

irb> RubyVM::InstructionSequence.compile(%q(x=5;puts "aaa #{x**3}")).to_a
=> ["YARVInstructionSequence/SimpleDataFormat", 2, 0, 1, {:arg_size=>0, :local_size=>2, :stack_max=>4}, "<compiled>", "<compiled>", nil, 1, :top, [:x], 0, [], [1, [:trace, 1], [:putobject, 5], [:setlocal_OP__WC__0, 2], [:trace, 1], [:putself], [:putobject, "aaa "], [:getlocal_OP__WC__0, 2], [:putobject, 3], [:opt_send_simple, {:mid=>:**, :flag=>256, :orig_argc=>1, :blockptr=>nil}], [:tostring], [:concatstrings, 2], [:opt_send_simple, {:mid=>:puts, :flag=>264, :orig_argc=>1, :blockptr=>nil}], [:leave]]]

確かにコンパイル時点で式が展開されている。

念のため、シングルクオート版も見てみた。

irb> RubyVM::InstructionSequence.compile(%q(x=5;puts 'aaa '+(x**3).to_s)).to_a
=> ["YARVInstructionSequence/SimpleDataFormat", 2, 0, 1, {:arg_size=>0, :local_size=>2, :stack_max=>4}, "<compiled>", "<compiled>", nil, 1, :top, [:x], 0, [], [1, [:trace, 1], [:putobject, 5], [:setlocal_OP__WC__0, 2], [:trace, 1], [:putself], [:putstring, "aaa "], [:trace, 1], [:getlocal_OP__WC__0, 2], [:putobject, 3], [:opt_send_simple, {:mid=>:**, :flag=>256, :orig_argc=>1, :blockptr=>nil}], [:opt_send_simple, {:mid=>:to_s, :flag=>256, :orig_argc=>0, :blockptr=>nil}], [:opt_plus, {:mid=>:+, :flag=>256, :orig_argc=>1, :blockptr=>nil}], [:opt_send_simple, {:mid=>:puts, :flag=>264, :orig_argc=>1, :blockptr=>nil}], [:leave]]]

"aaa "が:putobjectから:putstringになっているので若干速くなっている可能性があるが、逆に命令数が増えてしまった。

式展開がない場合でも、実行時点では、:putobjectと:putstringの差しかない。
というわけで、ダブルクオートとシングルクオートの速度差は体感できるほどではないことがバイトコードから理解できた。

追伸:
あくまでYARVが対象なので、Ruby 1.8ではどのような扱いなのかは依然としてはっきりしないが、もはや気にする必要はないと思われる。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?