nariです。

2011年7月3日0:01 KOSAKI Motohiro <kosaki.motohiro / gmail.com>:
>> GC::Profiler.enable
>> a = []
>> 10000000.times{a << "a".dup}
>> p GC::Profiler.total_time
>>
>> パッチ適用後: 1.410000000000001
>> バッチ適用前: 1.4899999999999998
>>
>> と、4%くらい劣化してます。
>> これくらいなら入れしまっていいかもしれませんが。
>> うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。
>
> おお、結構効きますね。こちらでも測ってみました。nariさんのに加えて
> 16段に一回だけチェックするようにしたやつ
>
> trunk: 1.3090170000000483
> nariパッチ: 1.3393349999998874
> kosakiパッチ: 1.294899000000145
>
> 16に意味は全然ないのですが、何回かに一回だけチェックという論理で
> オーバーヘッドはほぼ無視できるようです。
> (元のより速くなってるのはたぶん測定誤差です。すいません)
>
>
> ~/ruby/trunk% svn diff
> Index: gc.c
> ===================================================================
> --- gc.c        (revision 32355)
> +++ gc.c        (working copy)
> @@ -1614,7 +1614,7 @@
>     obj->as.basic.flags |= FL_MARK;
>     objspace->heap.live_num++;
>
> -    if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
> +    if (lev > GC_LEVEL_MAX || (((lev&0xF)==0) && stack_check())) {
>        if (!mark_stack_overflow) {
>            if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
>                *mark_stack_ptr = ptr;
>
>

以下のベンチマークで測ってみました。

GC::Profiler.enable
a = []
def make_depth(b, lev)
  return b << "a" if (lev-=1) <= 0
  b << []; make_depth(b.first, lev)
  return b
end
200000.times{a << make_depth([], 200)}
p GC::Profiler.total_time

trunk: 9.31
nariパッチ: 9.63
kosakiパッチ: 10.25

maskする分遅くなってしまうような気がします。

やはり、遠藤さんの仰ったように、stack_check()の引数にGC_WARTER_MARKを渡すように修正するのが
よさそうだと思っています。

-- 
Narihiro Nakamura (nari)