if {0} { '''memoize''' A package which can be used to cache, load and save the values of expensive pure function calls. '''HISTORY''' [DDG] 2004-06-03: A fix to memoize::save for handling strings with spaces '''SEE ALSO''' [memoizing], Perl Memoize Package [http://perl.plover.com/MiniMemoize/memoize.html] } ############################################################################## # AUTHOR: Dr. Detlef Groth # Copyright (c) Get it, use it, share it, improve it, but don't blame me. package provide memoize 0.1 namespace eval ::memoize { variable Memo } proc ::memoize::memoize {} { variable Memo set cmd [info level -1] if {[info level] > 2 && [lindex [info level -2] 0] eq "memoize::memoize"} return if { ! [info exists Memo($cmd)]} {set Memo($cmd) [eval $cmd]} return -code return $Memo($cmd) } proc ::memoize::save {file {cmd ""}} { variable Memo set names [array names Memo -glob $cmd*] if [catch { set out [open $file w 0600] }] { error "Could not open $file!" } else { foreach name $names { puts $out "set {memoize::Memo($name)} {$Memo($name)}" } } close $out } proc ::memoize::load {file} { variable Memo if {[file readable $file]} { source $file } } # testing actually longer than the code itself if {0} { # RS example proc memoize {} { global memo set cmd [info level -1] if {[info level] > 2 && [lindex [info level -2] 0] eq "memoize"} return if { ! [info exists memo($cmd)]} {set memo($cmd) [eval $cmd]} return -code return $memo($cmd) } proc fib x {expr {$x <=1? 1 : [fib [expr {$x-1}]] + [fib [expr {$x-2}]]}} proc fibm x {memoize; expr {$x <=1? 1 : [fibm [expr {$x-1}]] + [fibm [expr {$x-2}]]}} proc fibmp x {memoize::memoize; expr {$x <=1? 1 : [fibm [expr {$x-1}]] + [fibm [expr {$x-2}]]}} fib 20 ;#= 10946 fibm 20 ;#= 10946 fibmp 20 ;#= 10946 time {fib 32} ;#= 7757279 microseconds per iteration time {fib 32} ;#= 7763364 microseconds per iteration time {fib 32} ;#= 7927045 microseconds per iteration array unset memo time {fibm 32} ;#= 1365 microseconds per iteration time {fibm 32} ;#= 27 microseconds per iteration time {fibm 32} ;#= 28 microseconds per iteration array unset ::memoize::Memo time {fibmp 32} ;#= 97 microseconds per iteration time {fibmp 32} ;#= 29 microseconds per iteration time {fibmp 32} ;#= 28 microseconds per iteration memoize::save test.tmf array unset ::memoize::Memo memoize::load test.tmf time {fibmp 32} ;#= 33 microseconds per iteration time {fibmp 32} ;#= 29 microseconds per iteration time {fibmp 32} ;#= 28 microseconds per iteration } ---- [Category Package]