Although it can't hurt, I don't think `train` comes close to dominating the time?
Through the sophisticated profiling technique of commenting-out `or` branches in `correct`, I got the sense that the third one is the issue: (define (correct m s) (let ([best-known (λ (xs) (best-known m xs))]) (or (best-known (list s)) (best-known (edits1 s)) (best-known (append-map edits1 (edits1 s))) <-- if reached, very slow s))) real 0m16.527s user 0m14.554s sys 0m1.859s (define (correct m s) (let ([best-known (λ (xs) (best-known m xs))]) (or (best-known (list s)) (best-known (edits1 s)) (best-known (edits2 m s)) ;; what I posted yesterday s))) real 0m9.807s user 0m9.463s sys 0m0.266s (define (correct m s) (let ([best-known (λ (xs) (best-known m xs))]) (or (best-known (list s)) (best-known (edits1 s)) ;; (best-known (edits2 m s)) ;; skip it entirely s))) real 0m2.074s user 0m1.708s sys 0m0.184s p.s. `best-known` = combining `best` and `known` into a single pass for/fold: ;; Given a hash map and a list of words, returns ;; one of the words with the highest frequency. ;; Given an empty list returns #f (define (best-known ht xs) (car (for*/fold ([best (cons #f 0)]) ([x (in-list xs)] [v (in-value (hash-ref ht x #f))] ;; should default be 1? #:when v) (if (> v (cdr best)) (cons x v) best)))) ... which I thought might be faster but wasn't significant. ____________________ Racket Users list: http://lists.racket-lang.org/users