[racket-dev] An implementation of 'case' based on Clinger's "Rapid Case Dispatch in Scheme"

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Jul 23 19:57:02 EDT 2012

This is really nicely done --- thanks!

I've added your patch to the main repo.

Then I made small changes:

 * changed to generate vector and hash-table constants, instead of
   using `vector' and `make-hasheq', since the compiler and bytecode
   format deal better with constants;

 * removed the specialization of `eqv?' to `eq?' for some constants,
   because the bytecode compiler should take care of that (and covers
   more cases);

 * changed the handling of "other" constants to be like symbols and
   keywords, but using an `eqv?'-based hash table; and

 * reduced the symbol-or-keyword check that guarded a hash table
   lookup to use only `symbol?' if only symbols are mapped, etc.

You may want to double-check those changes.


At Sun, 22 Jul 2012 22:41:18 -0400, Jon Zeppieri wrote:
> On Sun, Jul 22, 2012 at 4:33 PM, Jon Zeppieri <zeppieri at gmail.com> wrote:
> >
> > However, it's possible that I was wrong about the cause of the bold
> > time difference. Today I updated my 'case-v3' branch with the changes
> > that have been committed to the plt master branch since the two
> > diverged, and I separately cloned the current plt master to a
> > different directory. (Previously, I had been using a tarball as the
> > control.) And I started running the build tests again. That's still
> > going on, but so far, the preliminary results are the opposite of the
> > ones from the other day. My 'case-v3' branch tends to build slightly
> > faster.
> >
> > Obviously, there are any number of things that can account for the
> > build time difference: background processes eating up CPU, physical
> > file location on disk, etc. If the numbers continue to come out as
> > they are now, I'll just conclude that the build time really isn't
> > significantly affected one way or the other.
> 
> 
> The Numbers
> 
> Summary: it's a wash, as far as I can tell. I no longer think that the
> new case implementation is a performance problem for building racket
> code. I would like to test runtime performance on real-world programs,
> too, as Eli suggests.
> 
> A. raco setup
> 
> time raco setup [with a "raco setup -c" between each build, of course]
> ========================
> Current 'case'
> 
> Build #1
> real	21m48.942s
> user	42m3.813s
> sys	24m19.049s
> 
> Build #2
> real	21m59.107s
> user	41m41.311s
> sys	24m25.283s
> 
> Build #4
> real	21m44.930s
> user	41m33.061s
> sys	23m52.597s
> 
> Build #5
> real	21m41.810s
> user	41m44.639s
> sys	23m49.387s
> 
> Build #6
> real	21m53.944s
> user	41m48.191s
> sys	23m57.606s
> ------------------------------
> Current 'case' summary
> 
> Average
> real   21m49.75s
> user  41m46.2s
> sys   24m04.78s
> 
> Max
> real   21m59.11s
> user  42m03.81s
> sys   24m25.28s
> 
> Min
> real   21m41.81s
> user  41m33.06s
> sys   23m49.39s
> 
> Deviation
> real   17.3s
> user  30.75s
> sys   35.9s
> 
> 
> ========================
> Clinger 'case'
> 
> Build #1
> real	21m47.926s
> user	41m42.205s
> sys	24m10.360s
> 
> Build #2
> real	22m4.643s
> user	41m36.205s
> sys	24m20.108s
> 
> Build #3
> real	22m1.669s
> user	41m45.768s
> sys	24m18.989s
> 
> Build #4
> real	21m52.921s
> user	41m51.076s
> sys	24m11.115s
> 
> Build #5
> real	21m51.656s
> user	41m37.121s
> sys	23m56.040s
> ------------------------------
> Clinger 'case' summary
> 
> Average
> real  21:55.76
> user 41:32.68
> sys  24:11.32
> 
> Max
> real  22:04.93
> user 41:51.08
> sys  24:20.11
> 
> Min
> real  21:47.93
> user 40:43.73
> sys  23:56.04
> 
> Deviation
> real  17
> user 1:07.34
> sys  24.07
> 
> 
> B. raco build
> 
> ** for the tests below, I took the times of the second run of the test
> for each implementation to prime the FS cache
> 
> 1) time ( for i in {1..10} ; do  rm compiler/compiled/zo-parse_rkt.zo;
> raco make compiler/zo-parse.rkt ; done )
> 
> current
> real	0m9.684s
> user	0m7.533s
> sys	0m1.696s
> 
> clinger
> real	0m9.556s
> user	0m7.376s
> sys	0m1.670s
> 
> 
> 2) time ( for i in {1..10} ; do  rm
> racket/private/compiled/serialize_rkt.zo; raco make
> racket/private/serialize.rkt ; done )
> 
> current
> real	0m6.142s
> user	0m4.668s
> sys	0m1.166s
> 
> clinger
> real	0m6.132s
> user	0m4.607s
> sys	0m1.161s
> 
> 
> 3) time ( for i in {1..10} ; do  rm racket/compiled/pretty_rkt.zo;
> raco make racket/pretty.rkt ; done )
> 
> current
> real	0m7.582s
> user	0m6.029s
> sys	0m1.143s
> 
> clinger
> real	0m7.527s
> user	0m6.093s
> sys	0m1.158s
> 
> 4) time ( for i in {1..10} ; do  rm racket/compiled/unit_rkt.zo; raco
> make racket/unit.rkt ; done )
> 
> current
> real	0m26.014s
> user	0m22.865s
> sys	0m2.679s
> 
> clinger
> real	0m26.073s
> user	0m22.904s
> sys	0m2.698s
> 
> 5) time ( for i in {1..10} ; do  rm
> scribble/compiled/latex-render_rkt.zo; raco make
> scribble/latex-render.rkt ; done )
> [ comparatively heavy use of 'case']
> 
> current
> real	0m9.070s
> user	0m7.255s
> sys	0m1.550s
> 
> clinger
> real	0m8.705s
> user	0m6.959s
> sys	0m1.467s
> 
> 
> 6) time ( for i in {1..10} ; do  rm
> plot/plot2d/compiled/plot-area_rkt.zo; raco make
> plot/plot2d/plot-area.rkt ; done )
> [no case expressions in source]
> 
> current
> real	0m14.172s
> user	0m11.326s
> sys	0m2.516s
> 
> clinger
> real	0m13.910s
> user	0m11.088s
> sys	0m2.480s
> 
> 
> C. Runtime performance
> 
> I only have one test so far: a test of a partial markdown parser. The
> parser is implemented in typed racket. The test of the parser is in
> untyped racket.
> _________________________
>   Racket Developers list:
>   http://lists.racket-lang.org/dev

Posted on the dev mailing list.