MiniD 2 - Tentative Release Candidate 1
Jarrett Billingsley
jarrett.billingsley at gmail.com
Tue Dec 9 21:52:18 PST 2008
On Wed, Dec 10, 2008 at 12:12 AM, davidl <davidl at 126.com> wrote:
>
> I got an impression that a scripting lang coroutine is less expensive than a function call? I guess coroutine in a scripting interpreted lang won't require any thread involved, and the suspension of the execution maybe even more costless compared to a return statement and reexecution of that function in the case of opApply.
The cost of a coroutine object in MiniD, as well as the cost of
calling it, depends on the compilation options
(http://www.dsource.org/projects/minid/wiki/API2/CompilationOptions).
If you don't specify any version flags when compiling MiniD, it will
use tango Fibers for coroutines created from native functions, and
will use its own system of pausing and resuming for coroutines created
from MiniD functions.
The cost of a coroutine resume/yield is more than a normal function
call, but it's still not a lot. For example, using MiniD coroutines,
I can perform around 1.6 million resume/yield pairs per second on my
Pentium M. Fibers aren't much slower; I still get about 1.25 million.
That's not going to be a bottleneck considering the speed of most
other operations.
Rather, the biggest cost with a coroutine is memory. A coroutine
object is relatively large compared to a function closure, and
depending on the compilation options, can also allocate D heap memory.
So for simple iteration tasks, it might be in the interest of
performance to try to write it in the form of a function iterator, and
if it gets to be too complex to be worth it, you can write it as a
coroutine.
> And I'm still not able to get opApply to work with coroutines, any example available?
> I always get the error message of "Iterated coroutine must be in the initial state", I've no clue about what it's going on.
When you use foreach on a coroutine, it has to be in the "initial"
state. The only times a coroutine can be in an initial state is (1)
immediately after they are created, before they are called even once,
and (2) after they have died and then had their .reset() method
called. A simple example:
function count(x) =
coroutine function()
{
yield() // first "empty" yield is important for foreach-able coroutines
for(i: 1 .. x + 1)
yield(i) // yield values after that
// when this coroutine returns here, iteration stops
}
foreach(v; count(4))
writeln(v) // prints 1 through 4
Notice that count is returning a new coroutine object each time you
call it, so the coroutine is always in the "initial" state.
There's more info on coroutines, including showing some iterators and
explaining their various states, at the following link:
http://www.dsource.org/projects/minid/wiki/LanguageSpec2/Functions#Coroutines
More information about the Digitalmars-d-announce
mailing list