| My humble parser.arc relies on 'in to detect whitespace (def whitespace? (ch)
(if (in ch #\space #\newline #\tab #\return) ch))
Inspecting the macro-expansion of this code one day, I figured it could run faster. 'in expands to an 'or form, which in turn expands to a bazillion nested function closures. But conceptually, all I need is (def whitespace? (ch)
(if (is ch #\space ) ch
(is ch #\newline ) ch
(is ch #\tab ) ch
(is ch #\return ) ch))
So here's a faster 'in (mac faster-in (x . choices)
(w/uniq g
`(let ,g ,x
(if ,@(mappend (fn (c) `((is ,g ,c) ,g)) choices)))))
Performance: arc> (time10 (repeat 43670 (in #\x #\space #\newline #\tab #\return)))
time: 642 msec.
nil
arc> (time10 (repeat 43670 (faster-in #\x #\space #\newline #\tab #\return)))
time: 607 msec.
nil
the 43670 is the size of arc.arc, hence faster-in should speed up parsing that file by about 4msec ... about 1.25% of total parsing time, so it's not going to change the world or anything.This is the original 'in, for comparison: (mac in (x . choices)
(w/uniq g
`(let ,g ,x
(or ,@(map1 (fn (c) `(is ,g ,c)) choices)))))
One difference: 'faster-in returns the found value, rather than 't, which in my case at least, is more useful.(parser.arc is with rainbow these days rather than anarki, if you're interested it's at http://github.com/conanite/rainbow/blob/master/src/arc/lib/parser.arc ) |