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)

Re: Benchmarking srfi-41, srfi-121 and srfi-158 Linus Björnstam 02 Aug 2020 10:03 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
>