Excellent -- thanks all. The binding approach works very well.

On Mar 19, 11:40 am, Jason Wolfe <jawo...@berkeley.edu> wrote:
> For recursive one-shot memoized functions, I've been using this:
>
> (defmacro memoized-fn [name args & body]
>   `(let [a# (atom {})]
>      (fn ~name ~args
>        (let [m# @a#
>              args# ~args]
>          (if-let [[_# v#] (find m# args#)]
>              v#
>            (let [v# (do ~...@body)]
>              (swap! a# assoc args# v#)
>              v#))))))
>
> e.g.,
> (memoized-fn fib [x]
>   (if (< n 2)
>       1
>     (+ (fib (- n 1)) (fib (- n 2)))))
>
> If you need every last bit of performance, you can replace the atom-
> map combination with a mutable Java HashMap.
>
> -Jason
>
> On Mar 18, 11:17 pm, B Smith-Mannschott <bsmith.o...@gmail.com> wrote:
>
> > On Fri, Mar 19, 2010 at 06:56, Greg  Fodor <gfo...@gmail.com> wrote:
>
> > > I would like to memoize bar such that the memory used for memoization
> > > is GC'ed at the end of the call to foo, and additionally the cache
> > > used for memoization is thread local (so no need for heavyweight
> > > synchronization tools like atoms, etc.) In Ruby, I would implement
> > > this as a simple local hash with the ||= operator through each
> > > iteration of a loop inside foo that calls bar.
>
> > ;; the "trick" I found is to explicitly deref the var binding the
> > ;; function to be memoized. This way fib's recursive calls will use
> > ;; the memoized binding established in
> > ;; use-fib-memoized-thread-locally.
>
> > (defn fib [n]
> >   (if (> 2 n) n
> >       (+ (@#'fib (dec n))
> >          (@#'fib (dec (dec n))))))
>
> > (defn use-fib-memoized-thread-locally [n]
> >   (binding [fib (memoize fib)]
> >     (fib n)))
>
> > ;; user> (time (fib 32))
> > ;; "Elapsed time: 1755.796366 msecs"  ;; SLOW
> > ;; 2178309
> > ;;
> > ;; user> (time (use-fib-memoized-thread-locally 32))
> > ;; "Elapsed time: 1.514927 msecs"     ;; FAST
> > ;; 2178309
> > ;;
> > ;; user> (time (fib 32))
> > ;; "Elapsed time: 2024.836838 msecs"  ;; SLOW, again
> > ;; 2178309
>
> > // Ben

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
"REMOVE ME" as the subject.

Reply via email to