[racket] generator performance

From: Patrick Useldinger (uselpa.list at gmail.com)
Date: Sun Sep 16 14:36:26 EDT 2012

On 16/09/2012 15:34, Neil Van Dyke wrote:

> 1. Use statistical profiler to see who is actually eating the time:
> http://doc.racket-lang.org/profile/index.html  Increasing the sampling
> resolution can help.

This is what I get - only quoting the highest self pct:
Profiling results
-----------------
   Total cpu time observed: 19244ms (out of 19495ms)
   Number of samples taken: 1541 (once every 12ms)
========================================================
                               for-each [5]        47.2%
                                loop [3]            52.8%
  [5] 8669(45.0%) 5286(27.5%) for-each 
.../collects/racket/private/map.rkt:48:13
                                for-each [5]        47.2%
                                loop [3]            46.5%
                                ??? [7]              1.4%

I've looked at the code and find nothing revealing

      46    (define for-each2
      47       (let ([for-each
      48              (case-lambda
      49               [(f l)
      50                (if (and (procedure? f)
      51                         (procedure-arity-includes? f 1)
      52                         (list? l))
      53                    (let loop ([l l])
      54                      (cond
      55                       [(null? l) (void)]
      56                       [else (begin (f (car l)) (loop (cdr l)))]))
      57                    (for-each f l))]

except maybe the file heading:

2 ;; #%kernel implements `map', `for-each', `andmap', and `ormap',
       3 ;;  but the JIT generates faster code, especially for the 
common cases.

How could I force the use of the kernel-implemented version of for-each?

> 2. Use DrRacket "Macro Stepper" to see exactly how the code expands.  I
> often just hit the "End" button, rather than stepping through. Adjusting
> "Macro hiding" thing at the bottom of the window can also help.

No user macros involved in this code.

> 3. Look at implementation of "generator" in the Racket source code.

I've had a look at ../collects/racket/generator.rkt (assuming this is 
the right place). All I can tell is that it uses continuations, as Eli said.

But the use of generator being the only difference between method a 
(fast, no generator) and method b (slow, generator) it probably boils 
down to "slow continuations".

Which makes me wonder if continuations are really usable in Racket (in 
terms of performance)?

> 4. Sam's disassembler:
> http://lists.racket-lang.org/dev/archive/2011-January/005321.html

I believe that's above my head, the last assembler I was fluent in was 6502.

>
> Neil V.
>

Thanks for the pointers!

Posted on the users mailing list.