Faster Enumerator#each by rb_block_call with current block

e$B1sF#$G$9!#e(B

e$B8=:_$Ne(B Enumerator#each e$B$O!"e(B1 e$B2s$N%V%m%C%/8F$S=P$7$Ge(B 2
e$B2sJ,$Ne(B yield e$B$r<B9Te(B
e$B$7$F$$$^$9!#e(B

  1. Enumerator#each e$B$,85$N%a%=%C%I$re(B rb_block_call e$B$G8F$Ve(B
    (e$B$3$N$H$-%V%m%C%/$H$7$Fe(B enumerator_each_i e$B$rM?$($ke(B)
  2. e$B85$N%a%=%C%I$,e(B yield e$B$7$F8=:_$N%V%m%C%/e(B
    (enumerator_each_i) e$B$r8F$Ve(B
  3. enumerator_each_i e$B$,e(B yield e$B$7$F<B:]$N%V%m%C%/$r8F$Ve(B

e$B$=$3$Ge(B rb_block_call
e$B$K8=:$N%V%m%C%/$rEO$;$k$h$&$K$7$F$$^$7$?!#e(B
e$B$3$&$9$k$H!"e(Byield e$B$Oe(B 1 e$B2s$G:Q$_$^$9!#e(B

  1. Enumerator#each e$B$,85$N%a%=%C%I$re(B rb_block_call e$B$G8F$Ve(B
    (e$B$3$N$H$-%V%m%C%/$H$7$F8=:_$N%V%m%C%/$r$=$N$^$^EO$9e(B)
  2. e$B85$N%a%=%C%I$,e(B yield e$B$7$F<B:]$N%V%m%C%/$r8F$Ve(B

e$B0J2<$N%Y%s%A%^!<%/$G;n$9$H!"%Q%C%AA0$Ge(B 1.49 e$BIC!"%Q%C%A8e$Ge(B
1.00 e$BIC$He(B
e$B$J$j$^$7$?!#e(B

GC.disable
a = [0] * 5000000
t = Time.now
a.to_enum.each {|x| }
p Time.now - t

e$B$A$J$_$Ke(B a.to_enum.each e$B$NBe$o$j$Ke(B a.each
e$B$HD>@\8F$s$@>l9g$G$be(B 1.00 e$BICe(B
e$B$G$9!#%a%=%C%I$r%Y!<%9$H$7$?e(B Enumerator e$B$,e(B to_enum
e$B$7$J$$>l9g$HB=?’$J$$e(B
e$BB.EY$K$J$C$?$H;W$$$^$9!#e(B

e$B$3$NOC$Oe(B Enumerator e$B$KFC2=$7$?OC$G$O$J$/!"e(BARGF.each_line
e$B$de(B each_byte
e$B$J$I$bF1$8$h$&$Ke(B 2 e$BCJ3,e(B yield
e$B$K$J$C$F$$$?$N$G!"8=:_$N%V%m%C%/$rD>@\e(B
e$BEO$9$h$&$K$7$?$H$3$m!"0J2<$,e(B 0.20 e$BIC$+$ie(B 0.18
e$BIC$K9bB.2=$7$^$7$?!#e(B

ruby -e ‘$<.each_line {|l| }’ *.c

e$B6qBNE*$J%Q%C%A$NFbMF$O!"e(Brb_block_call e$B$Ne(B bl_proc e$B$Ke(B
NULL e$B$,EO$5$l$?$ie(B
e$B8=:$N%V%m%C%/$r;H$&$h$&$K$9$k$H$$$&$b$N$G$9!#e(B
e$B%3%
%C%H$7$F$b$$$$$G$7$g$&$+!#e(B

diff --git a/enumerator.c b/enumerator.c
index 7c50f3d…34d16c0 100644
— a/enumerator.c
+++ b/enumerator.c
@@ -330,12 +330,6 @@ enumerator_allocate(VALUE klass)
}

static VALUE
-enumerator_each_i(VALUE v, VALUE enum_obj, int argc, VALUE *argv)
-{

  • return rb_yield_values2(argc, argv);
    -}

-static VALUE
enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, VALUE
*argv)
{
struct enumerator *ptr;
@@ -473,7 +467,7 @@ static VALUE
enumerator_each(VALUE obj)
{
if (!rb_block_given_p()) return obj;

  • return enumerator_block_call(obj, enumerator_each_i, obj);
  • return enumerator_block_call(obj, 0, obj);
    }

static VALUE
diff --git a/io.c b/io.c
index 643455e…3b8bd25 100644
— a/io.c
+++ b/io.c
@@ -9148,7 +9148,7 @@ argf_each_line(int argc, VALUE *argv, VALUE argf)
RETURN_ENUMERATOR(argf, argc, argv);
for (;:wink: {
if (!next_argv()) return argf;

  • rb_block_call(ARGF.current_file, rb_intern(“each_line”), argc, argv,
    rb_yield, 0);
  • rb_block_call(ARGF.current_file, rb_intern(“each_line”), argc, argv,
    0, 0);
    ARGF.next_p = 1;
    }
    }
    @@ -9182,7 +9182,7 @@ argf_each_byte(VALUE argf)
    RETURN_ENUMERATOR(argf, 0, 0);
    for (;:wink: {
    if (!next_argv()) return argf;
  • rb_block_call(ARGF.current_file, rb_intern(“each_byte”), 0, 0,
    rb_yield, 0);
  • rb_block_call(ARGF.current_file, rb_intern(“each_byte”), 0, 0, 0, 0);
    ARGF.next_p = 1;
    }
    }
    @@ -9212,7 +9212,7 @@ argf_each_char(VALUE argf)
    RETURN_ENUMERATOR(argf, 0, 0);
    for (;:wink: {
    if (!next_argv()) return argf;
  • rb_block_call(ARGF.current_file, rb_intern(“each_char”), 0, 0,
    rb_yield, 0);
  • rb_block_call(ARGF.current_file, rb_intern(“each_char”), 0, 0, 0, 0);
    ARGF.next_p = 1;
    }
    }
    diff --git a/vm_eval.c b/vm_eval.c
    index f0b2316…9276f0a 100644
    — a/vm_eval.c
    +++ b/vm_eval.c
    @@ -828,9 +828,15 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
    if (state == 0) {
    iter_retry:
    {
  •  rb_block_t *blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
    
  •  blockptr->iseq = (void *)node;
    
  •  blockptr->proc = 0;
    
  •  rb_block_t *blockptr;
    
  •  if (bl_proc) {
    
  • blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
  • blockptr->iseq = (void *)node;
  • blockptr->proc = 0;
  •  }
    
  •  else {
    
  • blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
  •  }
     th->passed_block = blockptr;
    
    }
    retval = (*it_proc) (data1);

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

In message “Re: [ruby-dev:39874] faster Enumerator#each by rb_block_call
with current block”
on Sun, 13 Dec 2009 12:58:51 +0900, Yusuke ENDOH [email protected]
writes:

|e$B1sF#$G$9!#e(B
|
|e$B8=:_$Ne(B Enumerator#each e$B$O!"e(B1 e$B2s$N%V%m%C%/8F$S=P$7$Ge(B 2 e$B2sJ,$Ne(B yield e$B$r<B9Te(B
|e$B$7$F$$$^$9!#e(B

|e$B$=$3$Ge(B rb_block_call e$B$K8=:$N%V%m%C%/$rEO$;$k$h$&$K$7$F$$^$7$?!#e(B
|e$B$3$&$9$k$H!"e(Byield e$B$Oe(B 1 e$B2s$G:Q$_$^$9!#e(B

|e$B6qBNE*$J%Q%C%A$NFbMF$O!"e(Brb_block_call e$B$Ne(B bl_proc e$B$Ke(B NULL e$B$,EO$5$l$?$ie(B
|e$B8=:$N%V%m%C%/$r;H$&$h$&$K$9$k$H$$$&$b$N$G$9!#e(B
|e$B%3%
%C%H$7$F$b$$$$$G$7$g$&$+!#e(B

e$B$H$j$“$($:%”%$%G%#%"$OM-8z$=$&$J$N$G!"8_49@-LdBj$,$J$1$l$PF3e(B
e$BF~$7$F$b$h$$$N$G$O$J$$$G$7$g$&$+!#%3%_%C%H$7$F$/$@$5$$!#e(B

e$B1sF#$G$9!#e(B

2009e$BG/e(B12e$B7ne(B19e$BF|e(B16:59 Yukihiro M.
[email protected]:

|e$B6qBNE*$J%Q%C%A$NFbMF$O!"e(Brb_block_call e$B$Ne(B bl_proc e$B$Ke(B NULL e$B$,EO$5$l$?$ie(B
|e$B8=:$N%V%m%C%/$r;H$&$h$&$K$9$k$H$$$&$b$N$G$9!#e(B
|e$B%3%
%C%H$7$F$b$$$$$G$7$g$&$+!#e(B

e$B$H$j$“$($:%”%$%G%#%"$OM-8z$=$&$J$N$G!"8_49@-LdBj$,$J$1$l$PF3e(B
e$BF~$7$F$b$h$$$N$G$O$J$$$G$7$g$&$+!#%3%_%C%H$7$F$/$@$5$$!#e(B

e$B$"$j$,$H$&$4$6$$$^$9!#e(B
e$B$J$+$@$5$s$K$h$C$F$A$g$C$H=$@5$5$l$?%Q%C%A$r%3%_%C%H$7$^$7$?!#e(B

2009e$BG/e(B12e$B7ne(B20e$BF|e(B21:33 Yusuke ENDOH [email protected]:

e$B$J$+$@$5$s$K$h$C$F$A$g$C$H=$@5$5$l$?%Q%C%A$r%3%_%C%H$7$^$7$?!#e(B

test-all e$B$,Mn$A$F$$$^$9$M!#e(B

http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20091220T214000.log.txt.gz

2009e$BG/e(B12e$B7ne(B20e$BF|e(B23:27 Yusuke ENDOH [email protected]:

e$B$3$NLdBj$N860x$O$h$/$o$+$C$F$J$$$s$G$9$,!“$H$j$”$($:1sF#$Ne(B
e$B85$N%Q%C%Ae(B ([ruby-dev:39874]) e$B$J$iH/>I$7$J$$$H;W$$$^$9$N$Ge(B
e$B$=$C$A$G%3%_%C%H$7$J$*$7$^$7$?!#e(B

e$BD>$C$?46$8$O$7$^$;$s$M$'!#e(B

http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20091221T014100.log.txt.gz

e$B1sF#$G$9!#e(B

2009e$BG/e(B12e$B7ne(B20e$BF|e(B22:18 Tanaka A. [email protected]:

2009e$BG/e(B12e$B7ne(B20e$BF|e(B21:33 Yusuke ENDOH [email protected]:

e$B$J$+$@$5$s$K$h$C$F$A$g$C$H=$@5$5$l$?%Q%C%A$r%3%_%C%H$7$^$7$?!#e(B

test-all e$B$,Mn$A$F$$$^$9$M!#e(B

http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20091220T214000.log.txt.gz

e$B$“$”$“!”$9$_$^$;$s!#e(B
test-all e$B$7$?$D$b$j$@$C$?$s$G$9$,2?$+4V0c$($?$h$&$G$9!#e(B

e$B$3$NLdBj$N860x$O$h$/$o$+$C$F$J$$$s$G$9$,!“$H$j$”$($:1sF#$Ne(B
e$B85$N%Q%C%Ae(B ([ruby-dev:39874]) e$B$J$iH/>I$7$J$$$H;W$$$^$9$N$Ge(B
e$B$=$C$A$G%3%_%C%H$7$J$*$7$^$7$?!#e(B

(e$BK:$l$+$1$F$^$7$?$,e(B) e$B1sF#$b:G=i$O$J$+$@$5$s$HF1$8$h$&$Je(B
e$B%Q%C%A$r=q$$$F!“$3$Ne(B SEGV e$B$KAx6x$7$F!”$h$/$o$+$i$J$+$C$?$N$Ge(B
e$B6KNOM>7W$J$H$3$m$r$$$8$i$J$$%Q%C%A$K$7$?$N$G$7$?!#e(B

e$B1sF#$G$9!#e(B

2009e$BG/e(B12e$B7ne(B21e$BF|e(B2:08 Tanaka A. [email protected]:

2009e$BG/e(B12e$B7ne(B20e$BF|e(B23:27 Yusuke ENDOH [email protected]:

e$B$3$NLdBj$N860x$O$h$/$o$+$C$F$J$$$s$G$9$,!“$H$j$”$($:1sF#$Ne(B
e$B85$N%Q%C%Ae(B ([ruby-dev:39874]) e$B$J$iH/>I$7$J$$$H;W$$$^$9$N$Ge(B
e$B$=$C$A$G%3%_%C%H$7$J$*$7$^$7$?!#e(B

e$BD>$C$?46$8$O$7$^$;$s$M$'!#e(B

e$B$?$S$?$S$9$_$^$;$s!#85$N%Q%C%A$NDL$j$K$7$=$3$M$F$$$^$7$?!#e(B
e$B:#EY$3$=D>$C$?e(B (e$B$i$$$$$Je(B) e$B!#e(B

e$B?dB,$G$9$,!"e(Brb_iterate e$B$NJQ?te(B node e$B$,e(B converative GC
e$B$K$h$C$F%^!<%/e(B
e$B$5$l$F$k>u67$J$s$G$9$+$M!#e(B