473,805 Members | 1,887 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Optimizing multiple dispatch

I have a multiple disptacher which, conceptually, looks something like
this:

class Multimethod:

def __init__(self):
self.methods = {}

def __call__(self, *args):
return self.methods[tuple(map(type, args))](*args)

def add_method(self , method, *types):
self.methods[types] = method

foo = Multimethod()

def fooii(a, b):
print "We got two ints"

def foosb(a, b):
print "We got a string and a bar"

class bar(object): pass

foo.add_method( fooii, int, int)
foo.add_method( foosb, str, bar)

foo(1,2)
foo("a string", bar())

My actual code looks nothing like this[*], because it contains a
number of optimizations, and addresses some domain-specific
considerations which are not relevant in this context; but the code
shown should highlight the salient points.

Profiling suggests that "tuple(map(type , args))" is taking a
significant proportion of time in certain critical loops.

Do you have any suggestions about how to make in run faster? (Either
by optimizing "tuple(map(type , args)", or by using a completely
different organization for the whole thing. There is almost certainly
no point in addressing any other implementation detail[*] of what is
shown here, as it is likely to be absent from my real code.)

[*] For example, there is no __call__ in my implementation; it's
implementeted as a closure.
Jul 18 '05 #1
15 1789
Jacek Generowicz <ja************ **@cern.ch> writes:
Profiling suggests that "tuple(map(type , args))" is taking a
significant proportion of time in certain critical loops.
Do you have any suggestions about how to make in run faster? (Either
by optimizing "tuple(map(type , args)", or by using a completely
different organization for the whole thing.


If the arguments inside the loop have fixed types, then maybe you
could have a method to get the reference to the function (once)
outside the loop.

This would be like methodForSelect or in Objective-C.

--
Brian Gough

Network Theory Ltd,
Publishing the Python Manuals --- http://www.network-theory.co.uk/
Jul 18 '05 #2
Avoding map() may help:
tuple([type(a) for a in args])
Using generator expressions (aren't they in 2.4?) might or might not
help:
tuple(type(a) for a in args)

You could write a small extension to perform this operation without all
the Python function calls.

cdef extern from "Python.h":
extern int PyTuple_Check(o bject)
extern object PyTuple_New(int )
extern int PyTuple_GET_SIZ E(object)
extern void *PyObject_Type( void*)
extern void PyTuple_SET_ITE M(object, int, void*)
extern void *PyTuple_GET_IT EM(object, int)

def maptype(i):
if not PyTuple_Check(i ): raise TypeError
cdef int l
cdef int j
l = PyTuple_GET_SIZ E(i)
o = PyTuple_New(l)
for j from 0 <= j < l:
PyTuple_SET_ITE M(o, j, PyObject_Type(P yTuple_GET_ITEM (i, j)))
return o
print maptype.maptype (("", 0, 0.0, 0L, str, int, type))

(<type 'str'>, <type 'int'>, <type 'float'>, <type 'long'>, <type 'type'>, <type 'type'>, <type 'type'>)

$ timeit -s 's = ("", 0, 0.0, 0L, str, int, type); from maptype import maptype' 'maptype(s)'
100000 loops, best of 3: 2.41 usec per loop
$ timeit -s 's = ("", 0, 0.0, 0L, str, int, type)' -s 'def maptype(s): return tuple([type(i) for i in s])' 'maptype(s)'
10000 loops, best of 3: 25.3 usec per loop
$ timeit -s 's = ("", 0, 0.0, 0L, str, int, type)' -s 'def maptype(s): return tuple(map(type, s))' 'maptype(s)'
100000 loops, best of 3: 17 usec per loop

... hmm, map is faster than listcomp. my mistake!

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFAvy2pJd0 1MZaTXX0RAvgPAJ 9+smiDH0o+bo5rw wsOri1hl7jtIQCe KCXR
BE8bms1T8IJduTW e7+ivEwQ=
=Xtuc
-----END PGP SIGNATURE-----

Jul 18 '05 #3
[Hi, Brian, fancy meeting you here !]

Brian Gough <bj*@network-theory.co.uk> writes:
If the arguments inside the loop have fixed types, then maybe you
could have a method to get the reference to the function (once)
outside the loop.


Yup, we do that already ... it gives us more than a factor of 2
improvement in a particular politically important benchmark.

But, this must remain an option open to the user, and there is still a
need to make the thing go faster without pre-selection.
Jul 18 '05 #4
Jeff Epler <je****@unpytho nic.net> writes:
Avoding map() may help:
tuple([type(a) for a in args])
Nonononononoooo o! :-)
You could write a small extension to perform this operation without all
the Python function calls.

[... Pyrex ...] 100000 loops, best of 3: 2.41 usec per loop [... List comprehension ...] 10000 loops, best of 3: 25.3 usec per loop [... map ...] 100000 loops, best of 3: 17 usec per loop
(I'm pretty sure that should be 10**5 loops in the list comp case)

Hmm, ok, the extension seems to be significantly faster. This
surprises me, because everything that executes in
"tuple(map(type ,args))" is coded in C already, so I don't see where
the gain is coming from.

I've never got around to trying Pyrex ... and I won't be allowed to
depend on it formally. Would it be feasible to use Pyrex to generate
the extension source code and paste[*] that into my extension module?
IOW, is there a run-time dependence on Pyrex?
<ASIDE>
... hmm, map is faster than listcomp. my mistake!


:-)

I've asked for optimization advice a few times here, and usually the
responses include "replace map with a list comprehension" ... and yet
the map is always faster. I wonder where people get this idea that map
is slow ... until this started happening I had always assumed that
"everyone" knows that the map/reduce/filter family are the fastest
Python looping constructs.

</ASIDE>
[*] Ugh, I shudder at the thought, putting the products of code
generators into CVS really goes against my fundamental principles.
Jul 18 '05 #5
Jacek Generowicz <ja************ **@cern.ch> writes:
Hmm, ok, the extension seems to be significantly faster. This
surprises me, because everything that executes in
"tuple(map(type ,args))" is coded in C already, so I don't see where
the gain is coming from.


Forgot to mention: your map and list comp versions included an
unnecessary call to a pure Python function (maptype). The extension
you proposed would replace an inlined "tuple(map(type , args))", so we
don't get hit by pure Python function call overhead at that point[*].

Still, eliminating that overhead knocks off only one third of the
time, while your extension was better by a factor of 7 ... so there's
still a factor of 4.5ish to be had by coding it as an extension
(sorry, I don't have Pyrex, so I can't show the time):

-s 's = ("", 0, 0.0, 0L, str, int, type)' -s 'def maptype(s): return tuple(map(type, s))' 'maptype(s)'
100000 loops, best of 3: 4.73 usec per loop
-s 's = ("", 0, 0.0, 0L, str, int, type)' 'tuple(map(type , s))'
100000 loops, best of 3: 4.46 usec per loop
[*] There is a pure Python function call overhead I would like to
eliminate by recoding in C, but it concerns a closure (which Pyrex
doesn't allow, IIRC), and that seems a bit tricky to do.
Jul 18 '05 #6
Jacek Generowicz <ja************ **@cern.ch> writes:
(I'm pretty sure that should be 10**5 loops in the list comp case)


I'm sorry, ignore that, I was talking out of my ****
Jul 18 '05 #7
Am Donnerstag, 3. Juni 2004 16:55 schrieb Jacek Generowicz:
[*] Ugh, I shudder at the thought, putting the products of code
generators into CVS really goes against my fundamental principles.


Writing this module by hand shouldn't be much harder than writing it using
Pyrex. The Python/C-API is very clean, and there's good documentation in the
Python Documentation section on Python.org...

I guess you could squeeze out another 0.1 usecs by writing it by hand, because
Pyrex sometimes generates suboptimal C code, on another note ;)

Heiko.

Jul 18 '05 #8
Pyrex is just a translator, there's no dependency on a Pyrex library or
include file when you actually want to compile the generated .c

On Thu, Jun 03, 2004 at 04:55:19PM +0200, Jacek Generowicz wrote:
Jeff Epler <je****@unpytho nic.net> writes:
Avoding map() may help:
tuple([type(a) for a in args])


Nonononononoooo o! :-)

[...]
... hmm, map is faster than listcomp. my mistake!


:-)

I've asked for optimization advice a few times here, and usually the
responses include "replace map with a list comprehension" ... and yet
the map is always faster. I wonder where people get this idea that map
is slow ... until this started happening I had always assumed that
"everyone" knows that the map/reduce/filter family are the fastest
Python looping constructs.


No message about optimization should be without one downright wrong
suggestion.

The common wisdom about listcomp speed may apply when the body doesn't
include a function call, but the map version would include a lambda:
$ timeit 'map(lambda x:x+1, range(100))'
1000 loops, best of 3: 230 usec per loop
$ timeit '[x+1 for x in range(100)]'
10000 loops, best of 3: 156 usec per loop
Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFAv0QgJd0 1MZaTXX0RAmwoAJ 920fACmXQR0UWd0 3BMQybUuKWEOwCf WDPB
Yc059n1wXFyym54 rUNFnctg=
=2YRY
-----END PGP SIGNATURE-----

Jul 18 '05 #9
Jacek Generowicz <ja************ **@cern.ch> writes:
I've never got around to trying Pyrex ... and I won't be allowed to
depend on it formally. Would it be feasible to use Pyrex to generate
the extension source code and paste[*] that into my extension module?
IOW, is there a run-time dependence on Pyrex?


Probably not even necessary - doing the same operation directly in
your extension module with straight C code shouldn't be much work (the
example Pyrex code posted is largely just a set of calls tov the
Python API anyway already). About the only thing that can't be
written directly in C is probably the "raise TypeError" part, but for
that you can just set the error and return NULL from the function, I
believe.

-- David
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1453
by: Hung Jung Lu | last post by:
Hi, I try win32com.client.Dispatch('InternetExplorer.Application'), and it returns an instance of the running IE object. If there are multiple instances of IE running, how can I make sure I get the one I want? thanks, Hung Jung
31
2950
by: Chris S. | last post by:
Is there a purpose for using trailing and leading double underscores for built-in method names? My impression was that underscores are supposed to imply some sort of pseudo-privatization, but would using myclass.len() instead of myclass.__len__() really cause Python considerable harm? As much as I adore Python, I have to admit, I find this to be one of the language's most "unPythonic" features and a key arguing point against Python. I've...
4
2408
by: Leslaw Bieniasz | last post by:
Cracow, 20.09.2004 Hello, I need to implement a library containing a hierarchy of classes together with some binary operations on objects. To fix attention, let me assume that it is a hierarchy of algebraic matrices with the addition operation. Thus, I want to have a virtual base class class Matr;
8
1698
by: J. Black | last post by:
Hello everyone - I've been developing an incident tracking and reporting system for an emergency services outfit that I work with part time. It's going well, except for one fly in the ointment. The situation is this - I have a dispatch form that is used by dispatchers to track incidents. An incident number is automatically assigned with an AutoNumber field once a dispatcher initiates an incident by opening the dispatch form. I have...
6
1827
by: G.Ashok | last post by:
Hi, Does anybody know how Multiple polymorphism can be done in VB.NET or DOT doesn't support it? Is there any third party extensions available like for Java to do this? Regards, ....Ashok ------------------------------------------------------------------------ "It is beautiful for an engineer to shape and design the same way
1
2970
by: vinoraja | last post by:
There are a number of reasons we don't implement Multiple Implementation Inheritance directly. (As you know, we support Multiple Interface Inheritance). However, I should point out that it's possible for compilers to create MI for their types inside the CLR. There are a few rough edges if you go down this path: the result is unverifiable, there is no interop with other languages via the CLS, and in V1 and V1.1 you may run into deadlocks...
60
4951
by: Shawnk | last post by:
Some Sr. colleges and I have had an on going discussion relative to when and if C# will ever support 'true' multiple inheritance. Relevant to this, I wanted to query the C# community (the 'target' programming community herein) to get some community input and verify (or not) the following two statements. Few programmers (3 to7%) UNDERSTAND 'Strategic Functional Migration
3
6960
by: tyler.schlosser | last post by:
Hi there, I am trying to launch a program called AmiBroker using the command: AB = win32com.client.Dispatch("Broker.Application") However, I have a dual-core CPU and would like to launch two instances of AmiBroker. I know it is possible to run two instances simultaneously since it is easy to do manually by double-clicking the AmiBroker.exe file twice. However, when I write two lines of code like this:
3
3777
by: Tigera | last post by:
Greetings, I too have succumbed to the perhaps foolish urge to write a video game, and I have been struggling with the implementation of multiple dispatch. I read through "More Effective C++" by Scott Meyers, and though I am impressed with his implementation, I wanted to find a way to use multiple dispatch in a way that was less complicated. Forgive me if the result, below, has been posted before or written of before - I haven't read...
0
9716
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9596
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10360
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10366
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10105
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7646
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6876
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5677
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3845
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.