From 085dd494d7238f76a41e02e90664b91d5a83cb4d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 28 Dec 2019 09:17:41 -0600 Subject: [PATCH] cs: speed up `hash-map` and `hash-for-each` on mutable hash tables Specialize internal iteration to avoid the overhead of going though the `hash-iterate-...` interface for each step. --- racket/src/cs/rumble/hash.ss | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/racket/src/cs/rumble/hash.ss b/racket/src/cs/rumble/hash.ss index c977fe095b..43246a6a84 100644 --- a/racket/src/cs/rumble/hash.ss +++ b/racket/src/cs/rumble/hash.ss @@ -398,6 +398,8 @@ (for-each (lambda (p) (proc (car p) (cdr p))) (try-sort-keys (hash-map ht cons)))] [(intmap? ht) (intmap-for-each ht proc)] + [(mutable-hash? ht) + (mutable-hash-map ht proc #f)] [else ;; mutable, impersonated, and weak-equal: (let loop ([i (hash-iterate-first ht)]) @@ -418,6 +420,8 @@ (map (lambda (p) (proc (car p) (cdr p))) (try-sort-keys (hash-map ht cons)))] [(intmap? ht) (intmap-map ht proc)] + [(mutable-hash? ht) + (mutable-hash-map ht proc #t)] [else ;; mutable, impersonated, and weak-equal: (let loop ([i (hash-iterate-first ht)]) @@ -429,6 +433,32 @@ (|#%app| proc key val))) (loop (hash-iterate-next ht i)))))])])) +(define (mutable-hash-map ht proc map?) + ;; Inline iteration over the internal vector to avoid the overhead + ;; of calling `hash-iterate-...` for each step + (let vec-loop ([old-n 0] [try? #t]) + (let ([vec (prepare-iterate! ht old-n)]) + (let loop ([i old-n]) + (cond + [(= i (#%vector-length vec)) + (if try? + (vec-loop i (> i old-n)) + (if map? '() (void)))] + [else + (let ([p (#%vector-ref vec i)]) + (let ([key (car p)] + [val (cdr p)]) + (cond + [(or (eq? key #!bwp) + (eq? val #!bwp)) + (loop (fx+ i 1))] + [map? + (cons (|#%app| proc key val) + (loop (fx+ i 1)))] + [else + (|#%app| proc key val) + (loop (fx+ i 1))])))]))))) + ;; In sorted hash-table travesals, make some effort to sort the key. ;; This attempt is useful for making hash-table traversals more ;; deterministic, especially for marshaling operations.