Impressed

David Piepgrass qwertie256 at gmail.com
Sat Jul 28 11:32:57 PDT 2012


> I'd say this argument on which is "better", yield or ranges, is 
> a problem ill posed.

Yeah, since yielding is just a convenient way to implement an 
input range, asking which is better is like asking "Which is 
better, pick-up trucks or vehicles?"

> "yield" adds real, nontrivial value, and is not entirely 
> implementable as a library. Walter and I saw some uses of it in 
> C# at Lang.NEXT that were quite impressive.
>
> On the other hand yield's charter is limited when compared to 
> that of ranges. Yield goes with the very simple "go through 
> everything once" functionality, which is essentially input 
> ranges - only a tiny part of ranges can do.

> "yield" adds real, nontrivial value, and is not entirely 
> implementable as a library. Walter and I saw some uses of it in 
> C# at Lang.NEXT that were quite impressive.

Agreed. However, I have been looking at D's Fibers and I wonder 
if an optimized implementation of them could provide the same 
functionality reasonably well:

https://www.semitwist.com/articles/article/view/combine-coroutines-and-input-ranges-for-dead-simple-d-iteration

The only problem is performance (and perhaps memory usage, but 
there are ways to reduce that). Someone reported that a trivial 
fiber-based forward range had 26x the overhead of opApply for 
iteration (70s vs 2.7s for 1 billion iterations). I wonder if the 
fiber-switching could be optimized? But I looked at core/thread.d 
and unless I'm missing something, the fiber switch does not 
appear to do much work: it calls Thread.getThis() twice per 
switch (= 4 times per iteration), getStackTop() (= rt_stackTop) 
once, and a naked asm routine with 21 asm instructions. The 
entire yield() process contains no branches; call() additionally 
calls setThis() twice and checks if the Fiber threw an exception. 
What's the easiest way to time something in D? I'm curious if 
Thread.getThis() (= TlsGetValue()) is the bottleneck.

Anyway, stack-switching lets you do not only the same things as 
C# 2's "yield return" but as far as I can tell, it can also do 
everything that C# 5's "async/await" can do and more:

http://qscribble.blogspot.ca/2012/07/asyncawait-vs-stack-switching.html

i.e. stack switching can accomplish tasks that async/await 
cannot, while I don't know of any cases of the reverse. async is 
more limited because all functions involved in an async task must 
be explicitly marked and transformed by the compiler, but stack 
switching works no matter what code is involved; even C code can 
be called on an asynchronous fiber task.


More information about the Digitalmars-d mailing list