<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	>
<channel>
	<title>
	Comments on: Memoization in Ruby and Python	</title>
	<atom:link href="https://programmingzen.com/memoization-in-ruby-and-python/feed/" rel="self" type="application/rss+xml" />
	<link>https://programmingzen.com/memoization-in-ruby-and-python/</link>
	<description>Meditations on programming, startups, and technology</description>
	<lastBuildDate>Thu, 12 Nov 2015 03:33:02 +0000</lastBuildDate>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>
		By: Principles of Computing course on Coursera. My notes. &#124; Arseny&#8217;s Blog		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-29069</link>

		<dc:creator><![CDATA[Principles of Computing course on Coursera. My notes. &#124; Arseny&#8217;s Blog]]></dc:creator>
		<pubDate>Thu, 12 Nov 2015 03:33:02 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-29069</guid>

					<description><![CDATA[[&#8230;] Second thing I have learned from this course is recursion. I&#8217;m still very hesitant to use recursion in my programs, because it is hard to handle without deep understanding of what is going on. However, recursion is a great tool that makes a program cleaner. Also, it is important to use memoization for recursive functions, it will give a really great boost of speed to your program, otherwise recursion can take forever. The good source to learn more about it is here. [&#8230;]]]></description>
			<content:encoded><![CDATA[<p>[&#8230;] Second thing I have learned from this course is recursion. I&#8217;m still very hesitant to use recursion in my programs, because it is hard to handle without deep understanding of what is going on. However, recursion is a great tool that makes a program cleaner. Also, it is important to use memoization for recursive functions, it will give a really great boost of speed to your program, otherwise recursion can take forever. The good source to learn more about it is here. [&#8230;]</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Rob Reid		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-8665</link>

		<dc:creator><![CDATA[Rob Reid]]></dc:creator>
		<pubDate>Fri, 05 Feb 2010 04:46:54 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-8665</guid>

					<description><![CDATA[I did benchmark your suggestion, Michael, and it&#039;s a little slower:

0.000112s (Antonio&#039;s 2nd version)
0.000155s (your version)

But if you remove missing, the time goes down to 0.000099s:

def memoize2(function):
    cache = {}
    def decorated_function(*args):
        val = cache.get(args)
        if not val:
            val = function(*args)
            cache[args] = val
        return val
    return decorated_function

&quot;if args in cache&quot; seems safer, though.  If function(*args) == None, it will always be reevaluated for args.  Functions can also return object(), although that is admittedly less likely.]]></description>
			<content:encoded><![CDATA[<p>I did benchmark your suggestion, Michael, and it&#8217;s a little slower:</p>
<p>0.000112s (Antonio&#8217;s 2nd version)<br />
0.000155s (your version)</p>
<p>But if you remove missing, the time goes down to 0.000099s:</p>
<p>def memoize2(function):<br />
    cache = {}<br />
    def decorated_function(*args):<br />
        val = cache.get(args)<br />
        if not val:<br />
            val = function(*args)<br />
            cache[args] = val<br />
        return val<br />
    return decorated_function</p>
<p>&#8220;if args in cache&#8221; seems safer, though.  If function(*args) == None, it will always be reevaluated for args.  Functions can also return object(), although that is admittedly less likely.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Michael Foord		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6262</link>

		<dc:creator><![CDATA[Michael Foord]]></dc:creator>
		<pubDate>Thu, 21 May 2009 22:35:48 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6262</guid>

					<description><![CDATA[You can avoid the exception and the double lookup with code like:
&lt;pre&gt;
def memoize(function):
    cache = {}
    def decorated_function(*args):
        missing = object()
        val = cache.get(args, missing)
        if not val is missing:
            return val
        else:
            val = function(*args)
            cache[args] = val
            return val
    return decorated_function
&lt;/pre&gt;

As a micro-optimisation you could make both cache and missing keyword arguments to the inner function. Lookup of local variables is faster. Not benchmarked any of this...]]></description>
			<content:encoded><![CDATA[<p>You can avoid the exception and the double lookup with code like:</p>
<pre>
def memoize(function):
    cache = {}
    def decorated_function(*args):
        missing = object()
        val = cache.get(args, missing)
        if not val is missing:
            return val
        else:
            val = function(*args)
            cache[args] = val
            return val
    return decorated_function
</pre>
<p>As a micro-optimisation you could make both cache and missing keyword arguments to the inner function. Lookup of local variables is faster. Not benchmarked any of this&#8230;</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Antonio Cangiano		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6257</link>

		<dc:creator><![CDATA[Antonio Cangiano]]></dc:creator>
		<pubDate>Wed, 20 May 2009 12:15:03 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6257</guid>

					<description><![CDATA[That&#039;s interesting, Ivan. That was my very first approach too but I didn&#039;t like the idea of accessing the hash twice for each hit in the cache. Exception handling must be so expensive that it&#039;s still faster to do the double lookup. I modified the post to include this alternative as well.]]></description>
			<content:encoded><![CDATA[<p>That&#8217;s interesting, Ivan. That was my very first approach too but I didn&#8217;t like the idea of accessing the hash twice for each hit in the cache. Exception handling must be so expensive that it&#8217;s still faster to do the double lookup. I modified the post to include this alternative as well.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Ivan Baldin		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6256</link>

		<dc:creator><![CDATA[Ivan Baldin]]></dc:creator>
		<pubDate>Wed, 20 May 2009 11:34:08 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6256</guid>

					<description><![CDATA[You can speed python example even more if you replace &quot;try/except&quot; construct in your decorator with with &quot;if args in cache&quot;. I had ~40% speed increase on python 3 and ~95% on python 2.6.]]></description>
			<content:encoded><![CDATA[<p>You can speed python example even more if you replace &#8220;try/except&#8221; construct in your decorator with with &#8220;if args in cache&#8221;. I had ~40% speed increase on python 3 and ~95% on python 2.6.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Neil Cook		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6253</link>

		<dc:creator><![CDATA[Neil Cook]]></dc:creator>
		<pubDate>Wed, 20 May 2009 01:32:55 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6253</guid>

					<description><![CDATA[I have to disagree with ajuc that memoizing parameter-less function return values is not very useful. Whenever the cost of calculating the return value is high, and there is a possibility that the function may be called more than once, it is useful.

An example would be a result from a complex database query.]]></description>
			<content:encoded><![CDATA[<p>I have to disagree with ajuc that memoizing parameter-less function return values is not very useful. Whenever the cost of calculating the return value is high, and there is a possibility that the function may be called more than once, it is useful.</p>
<p>An example would be a result from a complex database query.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Antonio Cangiano		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6250</link>

		<dc:creator><![CDATA[Antonio Cangiano]]></dc:creator>
		<pubDate>Tue, 19 May 2009 15:22:11 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6250</guid>

					<description><![CDATA[Marco, you could declare a function that wraps an imported function, and memoize that one.]]></description>
			<content:encoded><![CDATA[<p>Marco, you could declare a function that wraps an imported function, and memoize that one.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: ajuc		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6249</link>

		<dc:creator><![CDATA[ajuc]]></dc:creator>
		<pubDate>Tue, 19 May 2009 14:36:35 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6249</guid>

					<description><![CDATA[adit: memoization isn&#039;t magic - it works only on functions that always return the same value for the same parameters.

So memoization will work for function without parameters, but only if this function always return the same value :) so it is not very useful.

BTW it works in such way - each call to function first checks if the function was called with the same arguments before, if it was, it returns the value it returned last time, if not, it calculates the value normally, and then keeps the value associated with parameters it was called.

So it is simple caching, and can be only used on &quot;pure&quot; (as in functional programming) functions.]]></description>
			<content:encoded><![CDATA[<p>adit: memoization isn&#8217;t magic &#8211; it works only on functions that always return the same value for the same parameters.</p>
<p>So memoization will work for function without parameters, but only if this function always return the same value 🙂 so it is not very useful.</p>
<p>BTW it works in such way &#8211; each call to function first checks if the function was called with the same arguments before, if it was, it returns the value it returned last time, if not, it calculates the value normally, and then keeps the value associated with parameters it was called.</p>
<p>So it is simple caching, and can be only used on &#8220;pure&#8221; (as in functional programming) functions.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Marco		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6246</link>

		<dc:creator><![CDATA[Marco]]></dc:creator>
		<pubDate>Tue, 19 May 2009 11:58:50 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6246</guid>

					<description><![CDATA[mmm but how to use it for a method that is coming from a library that we use ?
is there a way to decorate a method in an import statement or something like that ?
cheers
   Marco
p.s. I&#039;m interested in the python implementation.]]></description>
			<content:encoded><![CDATA[<p>mmm but how to use it for a method that is coming from a library that we use ?<br />
is there a way to decorate a method in an import statement or something like that ?<br />
cheers<br />
   Marco<br />
p.s. I&#8217;m interested in the python implementation.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Bram		</title>
		<link>https://programmingzen.com/memoization-in-ruby-and-python/#comment-6245</link>

		<dc:creator><![CDATA[Bram]]></dc:creator>
		<pubDate>Tue, 19 May 2009 09:48:22 +0000</pubDate>
		<guid isPermaLink="false">http://antoniocangiano.com/?p=771#comment-6245</guid>

					<description><![CDATA[JRuby 1.2.0 (ruby 1.8.6 patchlevel 287)  results:

                     user     system      total        real
Regular fib:     7.955000   0.000000   7.955000 (  7.955000)
Memoized fib:    0.004000   0.000000   0.004000 (  0.004000)]]></description>
			<content:encoded><![CDATA[<p>JRuby 1.2.0 (ruby 1.8.6 patchlevel 287)  results:</p>
<p>                     user     system      total        real<br />
Regular fib:     7.955000   0.000000   7.955000 (  7.955000)<br />
Memoized fib:    0.004000   0.000000   0.004000 (  0.004000)</p>
]]></content:encoded>
		
			</item>
	</channel>
</rss>
