On Wed, Jul 31, 2019 at 12:55:03PM +0300, Lassi Kortela wrote:
> We can now parse GitHub's public GraphQL schema (30k lines of text) in about
> two seconds using the Chicken Scheme compiler:
>
> $ csc test-read.scm
> $ time ./test-read github-schema.public.graphql >/dev/null
>
> real 0m2.256s
> user 0m2.132s
> sys 0m0.077s
>
> The library is 555 lines of code at
> <https://github.com/lassik/graphql-chicken/blob/master/graphql-read.scm>. It
> has a hand-rolled recursive-descent lexer and a packrat parser. We owe this
> accomplishment to the great packrat library. Without support like it I
> would've given up.
Hi Lassi,
Cool! Just a quick note: that timing seemed to be a bit on the slow side
so I checked and it seems you forgot to compile read-char-if into a
library. With ./test-read -:d you see these lines:
; loading ./read-char-if.import.scm ...
; including ./read-char-if.scm ...
Running it in the profiler (add -:p to the invocation) also shows the
majority of time being spent in <eval>, which is generally a bad sign :)
With that eval, I get these timings here:
./test-read ../schema.public.graphql > /dev/null 2.78s user 0.05s system 70% cpu 4.012 total
If I compile it into a .so file, I get better times:
./test-read ../schema.public.graphql > /dev/null 1.63s user 0.02s system 82% cpu 2.007 total
Still far from great. Most of the time is spent in string-index
in srfi-13. Inlining that with tweaks brought down the time to
1 second. Something like this:
(define (string-index str criteria)
(let ((end (string-length str)))
(let lp ((i 0))
(and (< i end)
(if (eq? criteria (string-ref str i)) i
(lp (+ i 1)))))))
Cheers,
Peter