Wide Finder performance

まつもと ゆきひろです

Tim B.のWide Finder ProjectでRubyの結果が妙に低い[1]ので自
分でも試してみました。

[1] ongoing by Tim Bray · WF XI: Results

で、私が書いたのは以下のようなプログラムです。

添付1 wf1.rb シングルプロセス版
添付2 wf2.rb マルチプロセス版

適当に乱数で生成したデータファイルを対象に実行してみましたが、
Pythonより速い、とは言いませんが、少なくとも何十倍も遅いとい
うことはなさそうです。マルチプロセス版はCPU数に合わせて変数j
の値を変更してください。私のマシンはデュアルコアだったので、
一番成績が良かったのはj=2の時でした。

プロファイルを取ったら無駄が見つかったので、さきほどtrunkに
チェックインしておきました。

あと、気がついたのはvm_yield_setup_argsで毎回rb_ary_new4()で
配列を作っていることです。yieldのたびに作るこの配列がけっこう
GCã«è² æ‹…ã«ãªã£ã¦ã„ã‚‹ã‚ˆã†ã§ã™ã€‚ã“ã®è¾ºã®ä»•çµ„ã¿ã¯ã‚ˆãã‚ã‹ã‚‰ãªã„
のですが、この配列の割り当てを減らせるとブロックの実行効率が
だいぶ改善できそうです。

e$B!!$5$5$@$G$9!%e(B

Yukihiro M. wrote:

e$B$"$H!“5$$,$D$$$?$N$Oe(Bvm_yield_setup_argse$B$GKh2se(Brb_ary_new4()e$B$Ge(B
e$BG[Ns$r:n$C$F$$$k$3$H$G$9!#e(Byielde$B$N$?$S$K:n$k$3$NG[Ns$,$1$C$3$&e(B
GCe$B$KIiC4$K$J$C$F$$$k$h$&$G$9!#$3$NJU$N;EAH$_$O$h$/$o$+$i$J$$e(B
e$B$N$G$9$,!”$3$NG[Ns$N3d$jEv$F$r8:$i$;$k$H%V%m%C%/$N<B9T8zN($,e(B
e$B$@$$$V2~A1$G$-$=$&$G$9!#e(B

e$B!!$9$_$^$;$s!$8=>]$r$3$A$i$G$b3NG’$7$?$$$N$G$9$,!$$I$&;n$9$N$+$o$+$je(B
e$B$^$;$s$G$7$?!%65$($FLc$($J$$$G$7$g$&$+!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:35059] Re: Wide Finder performance”
on Thu, 12 Jun 2008 10:16:44 +0900, SASADA Koichi [email protected]
writes:

|Yukihiro M. wrote:
|> e$B$"$H!"5$$,$D$$$?$N$Oe(Bvm_yield_setup_argse$B$GKh2se(Brb_ary_new4()e$B$Ge(B
|> e$BG[Ns$r:n$C$F$$$k$3$H$G$9!#e(Byielde$B$N$?$S$K:n$k$3$NG[Ns$,$1$C$3$&e(B
|> GCe$B$KIiC4$K$J$C$F$$$k$h$&$G$9!#$3$NJU$N;EAH$$O$h$/$o$+$i$J$$e(B
|> e$B$N$G$9$,!"$3$NG[Ns$N3d$jEv$F$r8:$i$;$k$H%V%m%C%/$N<B9T8zN($,e(B
|> e$B$@$$$V2~A1$G$-$=$&$G$9!#e(B
|
|e$B!!$9$
$^$;$s!$8=>]$r$3$A$i$G$b3NG’$7$?$$$N$G$9$,!$$I$&;n$9$N$+$o$+$je(B
|e$B$^$;$s$G$7$?!%65$($FLc$($J$$$G$7$g$&$+!%e(B

e$B$I$s$J%W%m%0%i%`$G$b$h$$$N$G$9$,!"%V%m%C%/$r;H$&$b$N$r<B9T$9e(B
e$B$k$He(B vm_yield_setup_args() e$B$NCf$Ge(B rb_ary_new4()
e$B$r8F$S$^$9!#e(B

e$B>r7o$H$7$F$O!"e(Blambda e$B$G$J$/e(B iseq->arg_rest e$B$,e(B -1
e$B$G$J$/!"e(B
iseq->arg_post_lene$B$,%;%C%H$5$l$F$$$J$$;~$K$O$+$J$i$:e(B
rb_ary_new4()e$B$^$?$Oe(Brb_ary_new()e$B$,8F$P$l$^$9!#e(B

e$B@hDx$Ne(Bwfe$B$N%W%m%0%i%`$@$He(B

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

e$B$NItJ,$+$ie(B

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)

e$B$H8F$P$l$F$$$^$9!#e(Brb_yield()e$B$+$i$R$H$D$@$1$NCM$,8F$P$l!"<u<he(B
e$BB&$,0l$D$@$1$7$+%Q%i%a!<%?$r<u$1$D$1$J$$;~$K$OG[Ns$r:n$k$N$Oe(B
e$BL5BL$J5$$,$9$k$N$G$9$,!#e(B

e$B$J$s$+4*0c$$$7$F$=$&$J5$$,$9$ke(B…e$B!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B!!$5$5$@$G$9!%e(B

Yukihiro M. wrote:

e$B>r7o$H$7$F$O!"e(Blambda e$B$G$J$/e(B iseq->arg_rest e$B$,e(B -1 e$B$G$J$/!"e(B
iseq->arg_post_lene$B$,%;%C%H$5$l$F$$$J$$;~$K$O$+$J$i$:e(B
rb_ary_new4()e$B$^$?$Oe(Brb_ary_new()e$B$,8F$P$l$^$9!#e(B

e$B!!e(Biseq->arg_rest e$B$,e(B -1 e$B$G$J$$!$$H$O!$e(Brest
e$B0z?t$,$"$k!$$H$$$&OC$G$9!%e(B
|a, *b| e$B$Ne(B b e$B$NItJ,$@$+$i!$G[Ns$r:n$C$F$$$^$9!%e(B

e$B@hDx$Ne(Bwfe$B$N%W%m%0%i%`$@$He(B

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

== disasm: <ISeq:block in @…/trunk/test.rb>======================
== catch table
| catch type: redo st: 0000 ed: 0025 sp: 0000 cont: 0000

catch type: next st: 0000 ed: 0025 sp: 0000 cont: 0025

local table (size: 2, argc: 1 [opts: 0, rest: -1, post: 0, block:
-1] s3)
[ 2] ongoing

e$B!!$3$l$r8+$k$H!$e(Barg_rest e$B$Oe(B -1 e$B$N$h$&$G$9!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:35064] Re: Wide Finder performance”
on Thu, 12 Jun 2008 11:00:10 +0900, SASADA Koichi [email protected]
writes:

|Yukihiro M. wrote:
|> e$B>r7o$H$7$F$O!"e(Blambda e$B$G$J$/e(B iseq->arg_rest e$B$,e(B -1 e$B$G$J$/!“e(B
|> iseq->arg_post_lene$B$,%;%C%H$5$l$F$$$J$$;~$K$O$+$J$i$:e(B
|> rb_ary_new4()e$B$^$?$Oe(Brb_ary_new()e$B$,8F$P$l$^$9!#e(B
|
|e$B!!e(Biseq->arg_rest e$B$,e(B -1 e$B$G$J$$!$$H$O!$e(Brest e$B0z?t$,$”$k!$$H$$$&OC$G$9!%e(B
||a, *b| e$B$Ne(B b e$B$NItJ,$@$+$i!$G[Ns$r:n$C$F$$$^$9!%e(B

e$B$“$l!”$J$K$+$*$+$7$$$G$9$M!#$b$&>/$73N$+$a$F$_$^$9!#e(B

e$B!!$5$5$@$G$9!%e(B

Yukihiro M. wrote:

e$B$G!"$=$3$G;H$o$l$F$$$?$N$Oe(Bscane$B$G$O$J$/e(Bfore$BJ8$G$7$?!#e(B

e$B$D$^$je(B

for line in ARGF

end

e$B$G$O%Q%i%a!<%?$,$R$H$D$7$+$J$/!“e(Byielde$B$K$b$R$H$D$7$+CM$,EO$5e(B
e$B$l$J$$$N$Ke(Biseq->arg_reste$B$,e(B0e$B$K$J$jG[Ns$H$7$FEO$5$l$^$9!#$^$”!"e(B

e$B!!$J$k$[$I!%e(B

e$B!!6D$k$H$*$j!$$3$NM}M3$Oe(B for
e$B$N0UL#$r=>MhDL$j87L)$KE,MQ$9$k$?$a$K!$e(B

for [vars] in [expr]; …
e$B$r!$e(B
[expr].each{|*tmp| vars = *tmp …}
e$B$HE83+$9$k$+$i$G$9!%e(B

e$B!!$A$g$C$H!$$3$l$r$J$s$H$+$9$kJ}K!$r;W$$$D$+$J$$$s$G$9$,!$$J$s$H$+$7e(B
e$B$?$[$&$,$$$$$G$7$g$&$+!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:35070] Re: Wide Finder performance”
on Thu, 12 Jun 2008 12:45:28 +0900, Yukihiro M.
[email protected] writes:

||Yukihiro M. wrote:
||> e$B>r7o$H$7$F$O!"e(Blambda e$B$G$J$/e(B iseq->arg_rest e$B$,e(B -1 e$B$G$J$/!“e(B
||> iseq->arg_post_lene$B$,%;%C%H$5$l$F$$$J$$;~$K$O$+$J$i$:e(B
||> rb_ary_new4()e$B$^$?$Oe(Brb_ary_new()e$B$,8F$P$l$^$9!#e(B
||
||e$B!!e(Biseq->arg_rest e$B$,e(B -1 e$B$G$J$$!$$H$O!$e(Brest e$B0z?t$,$”$k!$$H$$$&OC$G$9!%e(B
|||a, b| e$B$Ne(B b e$B$NItJ,$@$+$i!$G[Ns$r:n$C$F$$$^$9!%e(B
|
|e$B$“$l!”$J$K$+$
$+$7$$$G$9$M!#$b$&>/$73N$+$a$F$_$^$9!#e(B

iseq->arg_reste$B$,e(B0(!= -1)e$B$@$C$?$N$O!"@h$N%a!<%k$KE:IU$7$?e(B
wf1.rbe$B$G$O$J$/!“JL$N%W%m%0%i%`$G$7$?!#$4$a$s$J$5$$!#e(B
e$B$G!”$=$3$G;H$o$l$F$$$?$N$Oe(Bscane$B$G$O$J$/e(Bfore$BJ8$G$7$?!#e(B

e$B$D$^$je(B

for line in ARGF

end

e$B$G$O%Q%i%a!<%?$,$R$H$D$7$+$J$/!“e(Byielde$B$K$b$R$H$D$7$+CM$,EO$5e(B
e$B$l$J$$$N$Ke(Biseq->arg_reste$B$,e(B0e$B$K$J$jG[Ns$H$7$FEO$5$l$^$9!#$^$”!"e(B
e$B$3$l$re(B

ARGF.each do |line|

end

e$B$K$9$k$@$1$G$=$l$J$j$KB.$/$J$k$N$G5$$K$9$k$3$H$O$J$$$N$+$b$7e(B
e$B$l$^$;$s$,!#e(Bfore$BJ8$OB?=EBeF~$K$J$k$+$i$+$J$"!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:35072] Re: Wide Finder performance”
on Thu, 12 Jun 2008 14:19:12 +0900, SASADA Koichi [email protected]
writes:
|>
|> for line in ARGF
|> …
|> end
|>
|> e$B$G$O%Q%i%a!<%?$,$R$H$D$7$+$J$/!“e(Byielde$B$K$b$R$H$D$7$+CM$,EO$5e(B
|> e$B$l$J$$$N$Ke(Biseq->arg_reste$B$,e(B0e$B$K$J$jG[Ns$H$7$FEO$5$l$^$9!#$^$”!"e(B

|e$B!!6D$k$H$*$j!$$3$NM}M3$Oe(B for e$B$N0UL#$r=>MhDL$j87L)$KE,MQ$9$k$?$a$K!$e(B
|
| for [vars] in [expr]; …
|e$B$r!$e(B
| [expr].each{|*tmp| vars = *tmp …}
|e$B$HE83+$9$k$+$i$G$9!%e(B
|
|e$B!!$A$g$C$H!$$3$l$r$J$s$H$+$9$kJ}K!$r;W$$$D$+$J$$$s$G$9$,!$$J$s$H$+$7e(B
|e$B$?$[$&$,$$$$$G$7$g$&$+!%e(B

e$BM%@h=g0L$ODc$$$N$G$J$s$H$+$9$kJ}K!$r;W$$$D$$$F!“;~4V$,<h$l$?e(B
e$B$i!”$G9=$$$^$;$s!#e(B