Skip to content

Commit

Permalink
Reduce iterations in concatenate!
Browse files Browse the repository at this point in the history
This commit should reduce the amount of iterations in concatenate to N
where N is the sum of the lengths of the input lists.

The previous implementation iterated from the beginning in each
concatenation because of `last-pair`.

This implementation is significantly faster in this extreme case:

(concatenate! `(,(iota 50000) ,@(map list (iota 500))))

>> Previous implementation:
real	0m0.671s
user	0m0.658s
sys	0m0.013s

>> This implementation:
real	0m0.175s
user	0m0.174s
sys	0m0.001s

The tests is done using `time`, which is not reliable at all, but using
`(trace last-pair)` shows accurately what happens with the iterations.
  • Loading branch information
ekaitz-zarraga committed Jan 9, 2024
1 parent a67e759 commit 967b888
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions lib/srfi/1/misc.scm
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
(define (concatenate! lists)
(if (null? lists)
'()
(fold (lambda (el acc)
(cond
((null? acc) el)
((null? el) acc)
(else (begin (set-cdr! (last-pair acc) el) acc))))
(car lists)
(cdr lists))))
(let loop ((acc '())
(prev '())
(rem lists))
(cond
((null? rem) acc)
((null? acc) (let ((cur (car rem))) (loop cur cur (cdr rem))))
((null? (car rem)) (loop acc prev (cdr rem)))
(else (let ((cur (car rem)))
(set-cdr! (last-pair prev) cur)
(loop acc cur (cdr rem))))))))

(define (append-reverse rev tail)
(if (null? rev) tail (append-reverse (cdr rev) (cons (car rev) tail))))
Expand Down

0 comments on commit 967b888

Please sign in to comment.