From: "Glass_saga (Masaki Matsushita)" <glass.saga@...>
Date: 2013-09-18T23:39:47+09:00
Subject: [ruby-dev:47720]	[ruby-trunk - Feature #7368][Closed] rb_str_each_line()のパフォーマンス向上とリファクタリング


Issue #7368 has been updated by Glass_saga (Masaki Matsushita).

Status changed from Assigned to Closed

r42966でこのチケットのpatch3.diffとほぼ同様の変更をコミットしたので、こちらのチケットも閉じます。
----------------------------------------
Feature #7368: rb_str_each_line()のパフォーマンス向上とリファクタリング
https://bugs.ruby-lang.org/issues/7368#change-41880

Author: Glass_saga (Masaki Matsushita)
Status: Closed
Priority: Normal
Assignee: naruse (Yui NARUSE)
Category: core
Target version: next minor


rb_str_each_line()でmemmem(3)を使う事を[ruby-dev:45344] [Feature #6129]で提案しましたが、
string.cからmemmem(3)を直接使わずに検索をrb_memsearch()にまとめた上で、
検索文字列と被検索文字列の両方がvalidなencodingである場合と、そうでない場合に関数を分けてリファクタリングしたpatchを作りました。
(どちらかがinvalidな場合には、rb_enc_codepoint_len()で舐めていき途中でArgumentErrorを投げる必要があるので、旧来の処理を使う必要があります)

このpatchには以下の利点があります。

* string.c側でmemmem(3)の有無を意識する必要がない

* これまで検索文字列がrb_default_rsである場合にはrb_str_each_line()側でmemchr(3)を用いた最適化が施されていた(trunkのstring.cの6166行以降)が、
  rb_memsearch()を使えば検索文字列の長さに合わせて最適化された検索をしてくれるので、このような特別扱いが不要になる

* 検索文字列と被検索文字列のencodingがvalidなら、検索文字列がrb_default_rsでない場合のパフォーマンスが向上する
  
* これまでrb_str_each_line()の冒頭で宣言されていた多数の変数を分けた関数毎に局所化できるので、以前よりは読みやすくなる

また、以下のコードでベンチマークを取りました。

require 'benchmark'

str = "hogehifuga\n" * 100_0000

Benchmark.bm do |x|
  x.report("default rs") do
    10.times do
      str.each_line {}
    end
  end

  x.report("not default rs") do
    10.times do
      str.each_line("hi") {}
    end
  end
end

trunk(r37670):
       user     system      total        real
default rs  2.060000   0.000000   2.060000 (  2.055412)
not default rs  3.700000   0.000000   3.700000 (  3.698057)

proposed:
       user     system      total        real
default rs  2.100000   0.000000   2.100000 (  2.095167)
not default rs  2.150000   0.000000   2.150000 (  2.153824)

検索文字列がrb_default_rsな場合のパフォーマンスが低下していない事、検索文字列がrb_default_rsでない場合にはパフォーマンスが向上している事が確認できます。

手元ではtest-allが通っていますが、それなりにコードを削った上に関数を新設しているので、patchをレビューして頂けると大変助かります。
よろしくお願いします。


-- 
http://bugs.ruby-lang.org/