[#45637] [ruby-trunk - Feature #6440][Open] 引数にIOを渡した場合のMarshal.loadにバッファを持たせたい — "Glass_saga (Masaki Matsushita)" <glass.saga@...>

14 messages 2012/05/16

[#45670] [ruby-trunk - Bug #6479][Open] ipaddr.rbの受け付ける書式が、プラットフォームによって異なる — "kachick (Kenichi Kamiya)" <kachick1+ruby@...>

9 messages 2012/05/22

[ruby-dev:45648] [ruby-trunk - Feature #6440] 引数にIOを渡した場合のMarshal.loadにバッファを持たせたい

From: "Glass_saga (Masaki Matsushita)" <glass.saga@...>
Date: 2012-05-17 16:39:06 UTC
List: ruby-dev #45648
Issue #6440 has been updated by Glass_saga (Masaki Matsushita).


なかださん、田中さん、レビューとご意見をありがとうございます。

現在のMarshalの形式では全体のサイズを知る方法がない為に、バッファを持とうとするとどうしても読み過ぎてしまいます。
ungetcでは駄目となると、seekが可能なIOに対してのみバッファを持つようにして、最後にIO#seekで辻褄を合わせるというのはどうでしょうか。
高速化できるIOの種類が限られてしまいますが、互換性は崩さずに済むと思います。
----------------------------------------
Feature #6440: 引数にIOを渡した場合のMarshal.loadにバッファを持たせたい
https://bugs.ruby-lang.org/issues/6440#change-26684

Author: Glass_saga (Masaki Matsushita)
Status: Assigned
Priority: Normal
Assignee: nobu (Nobuyoshi Nakada)
Category: core
Target version: 2.0.0


=begin
現在の(({Marshal.load}))では、引数に(({IO}))を渡すと(({IO#getbyte}))や(({IO#read}))で当座に必要な部分のみの読み出しを繰り返すので
大量のメソッド呼び出しが発生し、そのコストが無視できません。
そこで、引数に(({IO}))を渡した場合の(({Marshal.load}))にバッファを持たせる事を提案します。

  require 'benchmark'
  require 'tempfile'

  ary = Array.new(1000){ "hoge" }
  file = Tempfile.new("foo")
  Marshal.dump(ary, file)

  Benchmark.bm do |x|
    x.report do
      100.times do
        file.rewind
        Marshal.load(file)
      end
    end
  end

  file.close

上記のベンチマークでバッファを持つようにしたrubyとtrunkを比較したところ、以下の結果となりました。

  trunk(r35660):
         user     system      total        real
     1.880000   0.000000   1.880000 (  1.874681)

  proposed:
         user     system      total        real
     0.180000   0.000000   0.180000 (  0.178556)

patchを添付します。
=end



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

In This Thread