まつもと ゆきひろです

In message "Re: [ruby-dev:35059] Re: Wide Finder performance"
    on Thu, 12 Jun 2008 10:16:44 +0900, SASADA Koichi <ko1 / atdot.net> writes:

|Yukihiro Matsumoto wrote:
|> あと、気がついたのはvm_yield_setup_argsで毎回rb_ary_new4()で
|> 配列を作っていることです。yieldのたびに作るこの配列がけっこう
|> GCに負担になっているようです。この辺の仕組みはよくわからない
|> のですが、この配列の割り当てを減らせるとブロックの実行効率が
|> だいぶ改善できそうです。
|
| すみません,現象をこちらでも確認したいのですが,どう試すのかわかり
|ませんでした.教えて貰えないでしょうか.

どんなプログラムでもよいのですが、ブロックを使うものを実行す
ると vm_yield_setup_args() の中で rb_ary_new4() を呼びます。

条件としては、lambda でなく iseq->arg_rest が -1 でなく、
iseq->arg_post_lenがセットされていない時にはかならず
rb_ary_new4()またはrb_ary_new()が呼ばれます。

先程のwfのプログラムだと

data.scan(RE) { |ongoing| counts[ongoing[0]] += 1 }

の部分から

rb_yield(result) ->
rb_yield_0(1, &val) ->
vm_yield(GET_THREAD, argc, argv) ->
invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0) ->
vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr, type == VM_FRAME_MAGIC_LAMBDA)

と呼ばれています。rb_yield()からひとつだけの値が呼ばれ、受取
側が一つだけしかパラメータを受けつけない時には配列を作るのは
無駄な気がするのですが。

なんか勘違いしてそうな気がする...。

                                まつもと ゆきひろ /:|)