Benchmarking srfi-41, srfi-121 and srfi-158
Amirouche Boubekki
(01 Aug 2020 14:29 UTC)
|
Re: Benchmarking srfi-41, srfi-121 and srfi-158
Amirouche Boubekki
(01 Aug 2020 14:39 UTC)
|
Re: Benchmarking srfi-41, srfi-121 and srfi-158
John Cowan
(02 Aug 2020 00:58 UTC)
|
Re: Benchmarking srfi-41, srfi-121 and srfi-158
Amirouche Boubekki
(02 Aug 2020 08:11 UTC)
|
Re: Benchmarking srfi-41, srfi-121 and srfi-158 Linus Björnstam (02 Aug 2020 15:16 UTC)
|
Re: Benchmarking srfi-41, srfi-121 and srfi-158
John Cowan
(04 Aug 2020 14:18 UTC)
|
Re: Benchmarking srfi-41, srfi-121 and srfi-158
Marc Nieper-Wißkirchen
(02 Aug 2020 15:22 UTC)
|
IIRC make-coroutine-generator implemented using guiles prompts was, back in the 2.1 branch a very compelling alternative to generators using set! List-generator using delimited-continuation-coroutines was actually faster than list-generator using set! The use of set! is probably also the reason why srfi-171 is faster than srfi-158 for similar generators/ transducers. Amirouche uncovered one rather weird incompatibility in srfi-146 where it didn't produce the correct results, but other than that I have had very few problems with those kinds of generators. -- Linus Björnstam On Sun, 2 Aug 2020, at 10:10, Amirouche Boubekki wrote: > I few months back before proposing SRFI-167 and SRFI-168, I > benchmarked using Guile three kinds of generators: > > - srfi-41 > > - srfi-158 > > And another kind of generator that is not standard that look like the following: > > (define (traversi-range count) > (let loop ((index 0)) > (lambda () > (if (= index count) > (values #f #f) ;; This is the end of the traversi generator > (values index (loop (+ index 1))))))) > > So it looks somewhat like SRFI-121 / SRFI-158 generators, but with > different calling conventions, and in particular it works without any > set!. SRFI-41 and traversi generators were slower than R7RS > generators. > > I think SRFI-41 and traversi generators are more difficult to understand. > > Outside the performance differences between SRFI-41 and SRFI-158, > there is also a semantic difference, both offering different > "guarantees". I describe the difference between SRFI-41 and SRFI-158 > in terms of state. SRFI-41 are stateless or to say it otherwise, > SRFI-41 streams can be replayed. Whereas SRFI-158 and SRFI-121 are > stateful, once the code consumes a generator, it is gone, you can not > re-iterate over the generator without re-creating the whole generator > which is not necessarily easy when working e.g. with ports. Otherwise > said, SRFI-41 supports backtracking, whereas plain generators do not. > > Traversi generators are faster than SRFI-41, and support some limited > form of backtracking. I remember using traversi generators in a parser > combinator that requires backtracking. > > Mind the fact that at least the SRFI-158 sample implementation could > use some performance optimization by avoiding the use of > make-coroutine-generator. E.g. [1] > > make-coroutine-generator is very handy to build a generator quickly, > but it is not performant. > > I am working on a finger-tree implementation that used to rely on > make-coroutine-generator, when translating to > Continuation-Passing-Style, it is much faster. It is faster than > make-coroutine-generator implemented with call/1cc [0]. Similarly, > SRFI JSON could use make-coroutine-generator but would be much slower > (but also much more readable). > > While I am at it, when implementing generators, you should properly > take care of end-of-file, I think once eof was produced, the generator > should always produce eof... > > [0] https://www.scheme.com/csug8/control.html#./control:s6 > [1] > https://github.com/amirouche/guile-arew/commit/01dbf6353d6ad55759221ede823a33d311516234#diff-fca38fa8286c100b4e5f5180ed87e58e >