Hi, Linus Björnstam <linus.bjorns...@veryfast.biz> skribis:
> On Mon, 4 May 2020, at 11:36, Ludovic Courtès wrote: > >> > One thing I found is that `match` is slow. The code looked nicer but had >> > to change it back to lets and conds as the performance >> > increase was ~2 seconds. >> >> Oh, in which case exactly? And are you sure your hand-written code is >> equivalent to the ‘match’ code (it’s common for hand-written code to be >> more lax than ‘match’)? >> >> One thing to pay attention to is the use of ‘list?’, which is O(N), and >> is implied by ellipses in ‘match’. If you want to use ‘match’ in a way >> that avoids ‘list?’, write patterns such as (a . b) instead of (a b ...). >> It doesn’t have the same meaning, but often the end result is the same, >> for instance because you’ll later match on ‘b’ anyway. >> >> (I wish we can one day have a proper list type disjoint from pairs…) > > The change is here: he is only matching against chars and predicates: > https://github.com/aconchillo/guile-json/commit/ad4b06d86e4822466983d00f55474c8f664b538d It would be nice if you could pinpoint which one of these changes causes a difference, because: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,optimize (match (peek-char port) ((? eof-object?) x) ((? whitespace?) w) (_ e)) $84 = (let ((v (peek-char port))) (cond ((eof-object? v) x) ((whitespace? v) w) (else e))) --8<---------------cut here---------------end--------------->8--- What might make a difference is the code bloat when using ‘or’: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,optimize (match (peek-char port) ((or #\a #\b #\c #\d) x)) $86 = (let ((v (peek-char port))) (cond ((equal? v #\a) x) ((equal? v #\b) x) ((equal? v #\c) x) ((equal? v #\d) x) (else ((@@ (ice-9 match) error) 'match "no matching pattern" v) #f))) --8<---------------cut here---------------end--------------->8--- but even that sounds unlikely. You’re compiling with -O2, right? Thanks, Ludo’.