<div dir="ltr"><div><div><div><div><div><div><div>Hi,<br><br></div>I've been developing an implementation of Python in Racket, where I'm implementing Python's dictionaries over Racket custom hash tables.<br><br>
</div>While my occasional benchmarks typically show better performance on Racket programs than their Python equivalents, Racket's hash tables generally seem to be slower than Python's dicts.<br><br></div>I've set up this benchmark in Racket:<br>
<br><br>#lang racket<br><br>(define alphabet "abcdefghijklmnopqrstuvwxyz")<br>(define (random-word n)<br> (build-string n (lambda (x) (string-ref alphabet (random 23)))))<br><br>(define words (for/list ([k 1000000])<br>
(random-word 3)))<br>(define d (make-hash))<br><br>(time (for ([w words])<br> (if (hash-has-key? d w)<br> (hash-set! d w (add1 (hash-ref d w)))<br> (hash-set! d w 1))))<br><br>
<br></div>And its equivalent in Python:<br><br><br>import random<br>import time<br><br>alphabet = "abcdefghijklmnopqrstuvwxyz"<br>def random_word(n):<br> return ''.join([random.choice(alphabet) for i in range(n)])<br>
<br>words = [random_word(3) for k in xrange(1000000)]<br>d = {}<br><br>a = time.time()<br>for w in words:<br> if w in d:<br> d[w] = d[w] + 1<br> else:<br> d[w] = 1<br>b = time.time()<br>print b-a, 'seconds'<br>
<br><br></div>The Racket example yields running times of around 500 ms (running on Racket v6.0.1) while the Python example yields running times of around 330 ms (running on Python 2.7.3).<br><br></div>I find this unusual because Python is somewhat more dynamic than Racket, since <br>
</div>(a) Python's equality and hashing functions have to dispatched at runtime for each key;<br><div>(b) referencing and setting values in a Python dict is done using a very general operator, [], whose behaviour also has to be dispatched at runtime, unlike the more specific hash-ref and hash-set! Racket functions.<br>
<br></div><div>Is there something I'm missing about Racket's hash tables which explains this slower speed?<br><br></div><div>Thanks,<br>Pedro Ramos<br></div></div>