Raku / nqp

NQP
Other
343 stars 131 forks source link

nqp::iterator on lists is slower than manually indexing into lists #685

Open lizmat opened 3 years ago

lizmat commented 3 years ago

Using nqp::iterator:

$ time nqp -e 'my $l := nqp::list(1,2,3,4,5,6,7,8,9,10); my int $j := 10000000; while $j-- { my $iter := nqp::iterator($l); nqp::while($iter, my $a := nqp::shift($iter)) }'

real    0m1.477s
user    0m1.491s
sys 0m0.009s

versus using a manual indexer:

$ time nqp -e 'my $l := nqp::list(1,2,3,4,5,6,7,8,9,10); my int $j := 10000000; while $j-- { my int $i := -1; nqp::while(nqp::islt_i(($i := nqp::add_i($i,1)),nqp::elems($l)), my $a := nqp::atpos($l,$i)) }'

real    0m0.655s
user    0m0.671s
sys 0m0.008s
jnthn commented 3 years ago

I wondered to what degree it was setup cost vs iteration cost, but trying it with a bigger array:

$ time nqp -e 'my $l := nqp::list(); my int $p := 0; while $p++ < 10_000 { nqp::push($l, $p) }; my int $j := 10000; while $j-- { my int $i := -1; nqp::while(nqp::islt_i(($i := nqp::add_i($i,1)),nqp::elems($l)), my $a := nqp::atpos($l,$i)) }'

real    0m0.819s
user    0m0.784s
sys 0m0.024s

$ time nqp -e 'my $l := nqp::list(); my int $p := 0; while $p++ < 10_000 { nqp::push($l, $p) }; my int $j := 10000; while $j-- { my $iter := nqp::iterator($l); nqp::while($iter, my $a := nqp::shift($iter)) }'

real    0m1.736s
user    0m1.700s
sys 0m0.016s

Still shows a significant difference.

ab5tract commented 5 months ago

Still some time difference here (macOS M2 Pro, arm64, no JIT):

> time nqp -e 'my $l := nqp::list(); my int $p := 0; while $p++ < 10_000 { nqp::push($l, $p) }; my int $j := 10000; while $j-- { my int $i := -1; nqp::while(nqp::islt_i(($i := nqp::add_i($i,1)),nqp::elems($l)), my $a := nqp::atpos($l,$i)) }'
________________________________________________________
Executed in    1.15 secs    fish           external
   usr time    1.10 secs   84.00 micros    1.10 secs
   sys time    0.01 secs  588.00 micros    0.01 secs

> time nqp -e 'my $l := nqp::list(); my int $p := 0; while $p++ < 10_000 { nqp::push($l, $p) }; my int $j := 10000; while $j-- { my $iter := nqp::iterator($l); nqp::while($iter, my $a := nqp::shift($iter)) }'
________________________________________________________
Executed in    1.75 secs    fish           external
   usr time    1.72 secs   87.00 micros    1.72 secs
   sys time    0.01 secs  563.00 micros    0.01 secs