|
From: Csaba H. <csa...@cr...> - 2007-04-16 22:26:40
|
Hi!
Once upon a time I decided to benchmark how fast can various languages
(vms) do context switching between coroutines (or alikes they have).
Eg., for Python, I created a generator which yielded the numbers from 0
up to 100,000, and I iterated through it:
def gen():
for i in xrange(10**5):
yield i
for i in gen():
pass
... and I measured how fast is this executed, and I implemented it for
some other languages, too.
See the programs here:
http://creo.hu/~csaba/tmp/visible/oneHundredThousandGen/
http://creo.hu/~csaba/tmp/visible/oneHundredThousandGenNoBoot/
(The second location contains modified versions of the same programs
so that time measurement happens in the code itself, hence we can
see the runtimes without the vm bootup times. This adjustment is
not implemented for all the benchmarked languages.)
See discussion thread here:
http://thread.gmane.org/gmane.comp.lang.io/8387
within this, see some rudimentary results here:
http://article.gmane.org/gmane.comp.lang.io/8392
(Yes, I know of
http://shootout.alioth.debian.org/gp4/benchmark.php?test=message&lang=all
but I wanted to roll my own.)
* * *
Now I wanted to see how this works out with Factor.
Based on the sample code in the concurrency docs, I put together this:
!!!!!!!!!!!!!!!!! gentest.factor
USING: kernel arrays quotations match concurrency math ;
IN: gentest
: decr-server
receive {
{
{ ?from ?tag _ }
[ 1- dup ?tag swap 2array ?from send decr-server ]
}
} match-cond ;
: (gentest)
"x" over send-synchronous 0 > [ (gentest) ] when ;
: gentest (n -- server-process)
[ decr-server ] curry spawn
(gentest) ;
!!!!!!!!!!!!!!!!!!
Running
10 gentest
is fine; but when I wanted to test
100000 gentest
it dropped a "Call stack overflow" after some time.
Why does that happen, given that Factor features TCO?
Is there a more idiomatic/direct/efficient way to do this? I can imagine
that the message passing machinery of the concurrency code is a
significant overhead.
Csaba
|