Advent 2021, day 15: speed up.

Racket 8.3 had a performance regression that caused hashing pairs of
small numbers to take a long time. Using a vector made it substantially
faster (2 min -> 15 s).

See also [1] for upstream bug report.

[1] https://github.com/racket/racket/issues/4098
This commit is contained in:
Érico Nogueira 2021-12-18 21:54:43 -03:00
parent 87e6927028
commit becc8a3487
1 changed files with 10 additions and 10 deletions

View File

@ -20,7 +20,7 @@
(vector-ref (vector-ref sv y) x))
(define (new-pos x y ex ey)
(cons (+ x (* h ex)) (+ y (* v ey))))
(vector (+ x (* h ex)) (+ y (* v ey))))
(define (fix-value x y)
(let*-values ([(ex x) (quotient/remainder x h)] [(ey y) (quotient/remainder y v)] [(val) (+ (access x y) ex ey)])
@ -29,28 +29,28 @@
val)))
(define g (weighted-graph/directed null))
(match-let ([(cons h v) (new-pos h v (sub1 extra) (sub1 extra))])
(match-let ([(vector h v) (new-pos h v (sub1 extra) (sub1 extra))])
(for* ([x (in-range h)] [y (in-range v)])
(let ([p (cons x y)])
(let ([p (vector x y)])
(when (> x 0)
(add-directed-edge! g p (cons (sub1 x) y) (fix-value (sub1 x) y)))
(add-directed-edge! g p (vector (sub1 x) y) (fix-value (sub1 x) y)))
(when (> y 0)
(add-directed-edge! g p (cons x (sub1 y)) (fix-value x (sub1 y))))
(add-directed-edge! g p (vector x (sub1 y)) (fix-value x (sub1 y))))
(when (< x (sub1 h))
(add-directed-edge! g p (cons (add1 x) y) (fix-value (add1 x) y)))
(add-directed-edge! g p (vector (add1 x) y) (fix-value (add1 x) y)))
(when (< y (sub1 v))
(add-directed-edge! g p (cons x (add1 y)) (fix-value x (add1 y))))))
(let-values ([(vs ed) (dijkstra g (cons 0 0))] [(pos) (cons (sub1 h) (sub1 v))])
(add-directed-edge! g p (vector x (add1 y)) (fix-value x (add1 y))))))
(let-values ([(vs ed) (dijkstra g (vector 0 0))] [(pos) (vector (sub1 h) (sub1 v))])
(define (explore pos)
(display pos)
(display "\n")
(unless (equal? pos (cons 0 0)) (explore (hash-ref ed pos))))
(unless (equal? pos (vector 0 0)) (explore (hash-ref ed pos))))
;(explore pos)
(hash-ref vs pos)))
; print expanded grid
(when #f
(match-let ([(cons h v) (new-pos h v (sub1 extra) (sub1 extra))])
(match-let ([(vector h v) (new-pos h v (sub1 extra) (sub1 extra))])
(for* ([y (in-range v)] [x (in-range h)])
(when (= x 0)
(display "\n"))