<div dir="ltr"><div><div><div>Even more idiomatic:<br></div>(time (for ([w words])<br>        (hash-update! d w add1 0)))<br><br></div>But it seems to be slightly slower that Robby's version.<br></div><div><br></div>Laurent<br>

</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jul 24, 2014 at 11:26 AM, Robby Findler <span dir="ltr"><<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Not an answer to your direction question, but this is the more<br>
idiomatic way to write that and it seems to be a bit faster:<br>
<br>
(time (for ([w (in-list words)])<br>
        (hash-set! d w (add1 (hash-ref d w 0)))))<br>
<div><div class="h5"><br>
On Wed, Jul 23, 2014 at 10:54 AM, Pedro Ramos<br>
<<a href="mailto:pedropramos@tecnico.ulisboa.pt">pedropramos@tecnico.ulisboa.pt</a>> wrote:<br>
> Hi,<br>
><br>
> I've been developing an implementation of Python in Racket, where I'm<br>
> implementing Python's dictionaries over Racket custom hash tables.<br>
><br>
> While my occasional benchmarks typically show better performance on Racket<br>
> programs than their Python equivalents, Racket's hash tables generally seem<br>
> to be slower than Python's dicts.<br>
><br>
> 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>
> 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>
> The Racket example yields running times of around 500 ms (running on Racket<br>
> v6.0.1) while the Python example yields running times of around 330 ms<br>
> (running on Python 2.7.3).<br>
><br>
> I find this unusual because Python is somewhat more dynamic than Racket,<br>
> since<br>
> (a) Python's equality and hashing functions have to dispatched at runtime<br>
> for each key;<br>
> (b) referencing and setting values in a Python dict is done using a very<br>
> general operator, [], whose behaviour also has to be dispatched at runtime,<br>
> unlike the more specific hash-ref and hash-set! Racket functions.<br>
><br>
> Is there something I'm missing about Racket's hash tables which explains<br>
> this slower speed?<br>
><br>
> Thanks,<br>
> Pedro Ramos<br>
><br>
</div></div>> _________________________<br>
>   Racket Developers list:<br>
>   <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
><br>
_________________________<br>
  Racket Developers list:<br>
  <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
</blockquote></div><br></div>