Skip to content

Instantly share code, notes, and snippets.

@pminten
Created August 8, 2014 12:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pminten/b147b26935e22a2dbffa to your computer and use it in GitHub Desktop.
Save pminten/b147b26935e22a2dbffa to your computer and use it in GitHub Desktop.
Racket code to visualize how bad association lists are as an updating dictionary
#lang racket
; Quick and ugly benchmark to see how if association lists for
; smallish lists are quicker to update than hash tables.
; To run: open in DrRacket and press the Run button.
(require plot)
; List of words of varying length.
(define words
(list "aardvark" "banana" "clown" "dagger" "eat"
"friend" "goo" "happy" "interesting" "jolly"
"keen" "later" "many" "no" "probability"
"questionaire" "reachable" "static"
"terrifying" "under" "view" "wedge"
"xylophone" "yes" "zoinks"))
(define (make-pairs count)
(for*/list ([i (in-range count)]
[w words])
(cons w i)))
(define (build-hash-immutable pairs)
(for/fold ([acc (hash)]) ([pair (in-list pairs)])
(hash-update acc
(car pair)
(λ (old) (+ old (cdr pair)))
0)))
(define (build-hash-mutable pairs)
(define table (make-hash))
(for ([pair (in-list pairs)])
(hash-update! table
(car pair)
(λ (old) (+ old (cdr pair)))
0))
table)
(define (build-assoc pairs)
(for/fold ([acc (list)]) ([pair (in-list pairs)])
(dict-update acc
(car pair)
(λ (old) (+ old (cdr pair)))
0)))
(struct measurement (count hash-immutable hash-mutable assoc))
; Get the CPU time of running proc with as only argument arg.
; The proc is run 5 times, the highest and lowest time are discarded
; and the other three are averaged and returned. This should get rid
; of the worst outliers.
(define (bench proc arg)
(define times
(for/list [(n (in-range 5))]
(define-values (lst cpu real gc) (time-apply proc (list arg)))
cpu))
(define middle-three (take (drop (sort times <) 1) 3))
(/ (apply + middle-three) (length middle-three)))
(define (get-measurements)
(for/list ([count (in-range 0 1001 100)])
(displayln count) ; Current progress
(define pairs (make-pairs count))
(measurement count
(bench build-hash-immutable pairs)
(bench build-hash-mutable pairs)
(bench build-assoc pairs))))
(define (plot-measurements measurements)
(define (points-for accessor)
(for/list ([m measurements]) (list (measurement-count m) (accessor m))))
(plot
(list
(lines
(points-for measurement-hash-immutable)
#:color 1
#:label "immutable hash")
(lines
(points-for measurement-hash-mutable)
#:color 2
#:label "mutable hash")
(lines
(points-for measurement-assoc)
#:color 3
#:label "assoc list")
)
#:x-label "numbers"
#:y-label "milliseconds"))
(plot-measurements (get-measurements))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment