[ruby-dev:31764] Re: ordered/unordered st_table

From: Tanaka Akira <akr@...>
Date: 2007-09-08 15:44:19 UTC
List: ruby-dev #31764
In article <20070904090732.BEAC7E03D5@mail.bc9.jp>,
  Nobuyoshi Nakada <nobu@ruby-lang.org> writes:

> ついでに、st_tableの順序の有無を切替えるパッチです。

r13412 にパッチを当てて測ってみました。

要素の多い st_table (ただし Hash 以外) が効くはずなので、ま
ずはシンボルを大量に生成してみます。

パッチ前:
% time ./ruby -e 's = "a"; 1000000.times { s.intern; s.succ! }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize:    95048 kB
./ruby -e   6.52s user 0.12s system 99% cpu 6.667 total

パッチ後:
% time ./ruby -e 's = "a"; 1000000.times { s.intern; s.succ! }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize:    79336 kB
./ruby -e   6.92s user 0.12s system 98% cpu 7.169 total

95Mbytes から 79Mbytes と、それなりに減っています。16% くら
いですか。

また、(rdoc で問題になった) iv_tbl の影響をみるために 26個の
インスタンス変数があるオブジェクトをたくさん生成してみます。

パッチ前:
% time ./ruby -e '
class C
  def initialize
    @a = @b = @c = @d = @e = @f = @g = @h = @i = @j = @k = @l = @m =
    @n = @o = @p = @q = @r = @s = @t = @u = @v = @w = @x = @y = @z = 0
  end
end
a = []; 100000.times { a << C.new }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize:    96896 kB
./ruby -e   2.68s user 0.12s system 98% cpu 2.833 total

パッチ後:
% time ./ruby -e '
class C
  def initialize
    @a = @b = @c = @d = @e = @f = @g = @h = @i = @j = @k = @l = @m =
    @n = @o = @p = @q = @r = @s = @t = @u = @v = @w = @x = @y = @z = 0
  end
end
a = []; 100000.times { a << C.new }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize:    74420 kB
./ruby -e   2.60s user 0.11s system 97% cpu 2.774 total

これも 97Mbytes から 74Mbytes と、23% くらい減っています。

numtable で linked list を使いはじめる (順序をつけないことに
よる効果が出始める) のはインスタンス変数 6つなので、そこを測っ
てみると以下のようになります。

パッチ前:
% time ./ruby -e '
class C
  def initialize
    @a = @b = @c = @d = @e = @f = 0
  end
end
a = []; 100000.times { a << C.new }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize:    34348 kB
./ruby -e   0.86s user 0.05s system 98% cpu 0.920 total

パッチ後:
% time ./ruby -e '
class C
  def initialize
    @a = @b = @c = @d = @e = @f = 0
  end
end
a = []; 100000.times { a << C.new }
print File.read("/proc/#{$$}/status")[/^VmSize.*\n/]'
VmSize:    27576 kB
./ruby -e   0.80s user 0.06s system 99% cpu 0.873 total

この場合でも 34Mbytes から 28Mbytes と 20% くらい減っていま
す。

ひとつのオブジェクトに対してインスタンス変数を 1000個くらい
作れば劇的なメモリ削減を実現する例を作れるかもしれません。

なお、rdoc 自身も測りましたが、(当然のことではありますが) もはや
ぜんぜん効きません。
-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread

Prev Next