[#65451] [ruby-trunk - Feature #10333] [PATCH 3/1] optimize: "yoda literal" == string — ko1@...

Issue #10333 has been updated by Koichi Sasada.

9 messages 2014/10/07

[ruby-core:65889] Re: [ruby-trunk - Feature #10423] [PATCH] opt_str_lit*: avoid literal string allocations

From: Eric Wong <normalperson@...>
Date: 2014-10-24 07:58:28 UTC
List: ruby-core #65889
Sure, I'll show each instruction with comments inline:

"%d" % 5
--------
  [1,
  [:trace, 1],
  # 14 == OM_idMOD__String in generated opt_method.h
  # [:putstring, "%d"] was replaced with
  [:opt_str_lit_recv, ["%d", 14]],
  [:putobject, 5],
  [:opt_mod, {:mid=>:%, :flag=>256, :orig_argc=>1, :blockptr=>nil}],
  [:leave]]

  # I hope to optimize allocation on sprintf format strings too,
  # but that may be tricky...

str.tr("a", "A")
----------------
 [1,
  [:trace, 1],
  [:putself],
  [:opt_send_simple, {:mid=>:str, :flag=>280, :orig_argc=>0, :blockptr=>nil}],
  # both :opt_str_lit_tmask calls used to be :putstring
  # 55 == OM_idTr__String
  # 32 == OM_TMASK_String (1 << RUBY_T_STRING), also in opt_method.h
  [:opt_str_lit_tmask, ["a", 55, 32, 0]], # 0: offset to recv (str)
  [:opt_str_lit_tmask, ["A", 55, 32, 1]], # 1: offset to recv (str)
  [:opt_send_simple, {:mid=>:tr, :flag=>256, :orig_argc=>2, :blockptr=>nil}],
  [:leave]]]

Time.now.strftime("%Y")
-----------------------
 [1,
  [:trace, 1],
  [:getinlinecache, :label_9, 0],
  [:getconstant, :Time],
  [:setinlinecache, 0],
  :label_9,
  [:opt_send_simple, {:mid=>:now, :flag=>256, :orig_argc=>0, :blockptr=>nil}],
  # 63: OM_idStrftime__Time
  # for opt_str_lit_data, we must ensure class (Time) matches recv
  # because T_DATA may be almost anything
  [:opt_str_lit_data, ["%Y", 63, Time, 0]], # 0: offset to recv
  [:opt_send_simple,
   {:mid=>:strftime, :flag=>256, :orig_argc=>1, :blockptr=>nil}],
  [:leave]]]

In the future, I hope these optimizations can be applied to pure Ruby
classes and methods, as I mentioned in [ruby-core:65761]

I have been using the following insn-dump.rb script:

	require 'pp'
	pp RubyVM::InstructionSequence.compile(STDIN.read).to_a

In This Thread

Prev Next