Speed: bytecode vz C API calls

Jacek Generowicz jacek.generowicz at cern.ch
Tue Dec 9 16:55:30 EST 2003


Peter Otten <__peter__ at web.de> writes:

> Jacek Generowicz wrote:
> 
> > aahz at pythoncraft.com (Aahz) writes:
> > 
> >> I think you're going to need to write a solution that doesn't call
> >> functions (function unrolling, so to speak).  Instead of returning a
> >> memoizer function, just use a dict of dicts.
> > 
> > Sounds interesting. But how do I get the dictionary to use the
> > function which it is memoizing, to calculate values which haven't been
> > cached yet?
> 
> Guessing into the blue:
> 
> try:
>     result = cache[fun, args]
> except KeyError:
>     result = cache[fun, args] = fun(args)

Allow me to remind you of the memoizer I posted at the top of the thread:

  def memoize(callable):
      cache = {}
      def proxy(*args):
          try: return cache[args]
          except KeyError: return cache.setdefault(args, callable(*args))
      return proxy

One key feature of this is that I can use it to replace any[*]
function with a functionally equivalent but faster one, without having
to change any of the call sites of the original.

IIUC, Aahz suggested to replace the proxy function with a
dictionary. This sounds reasonable, as, after all, the proxy maps its
arguments to its return values, while a dictionary maps keys to
values. The whole point of this is that function call overhead is
large compared to dictionary lookup, which is (almost) all that the
proxy does. However, it's the "almost" that creates the problem. If
I'm prepared to mess around with the calls to the original functions
and replace them with your suggestion, then, of course the problem is
solved ... however, I _really_ do not want to replace the calls to the
original ...

> Maybe it's time to show some inner loop lookalike to the wider
> public for more to the point suggestions...


Sure.


  def foo(some_type):
      ...
      return something


  foo = memoize(foo)

  data = [int, float, my_class, his_class, str, other_class] * 10**6

  map(foo, data)  [+]



[*]  ... with hashable arguments, etc. etc.

[+] Can you see why I don't want to mess with the call site ?




More information about the Python-list mailing list