优化多个调度 [英] Optimizing multiple dispatch
问题描述
我有一个多个disptacher,在概念上看起来像
这个:
class Multimethod:
def __init __(self):
self.methods = {}
def __call __(self,* args):
return self.methods [元组(map(type,args))](* args)
def add_method(self,method,* types):
self.methods [types] =方法
foo = Multimethod()
def fooii(a,b):
打印我们有两个整数
def foosb(a,b):
print"我们有一个字符串和一个条形码;
班级栏(对象):传递
foo.add_method(fooii,int,int)
foo.add_method(foosb,str,bar)
foo(1,2)
foo(" a string",bar())
我的实际代码看起来不像这个[*],因为它包含了一些
的优化次数,并且解决了一些特定于域的问题
考虑哪些ar在这方面不相关;但显示的代码
应该突出显示要点。
分析表明元组(map(type,args))在某些关键循环中花费了大量的时间。
你对如何更快地运行有什么建议吗? (通过优化元组(map(type,args)或者通过使用一个完全不同的组织来完成整个事情,通过
。几乎可以肯定
没有必要解决这里显示的
的任何其他实现细节[*],因为它可能不在我的真实代码中。)
[*]例如,我的实现中没有__call__;它是
实现为闭包。
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.
推荐答案
Jacek Generowicz< ja ************** @ cern.ch>写道:
Jacek Generowicz <ja**************@cern.ch> writes:
分析表明tuple(map(type,args))在某些关键循环中占据了相当大的一部分时间。
你对如何更快地运行有任何建议吗?(或者
通过优化元组(map(type,args),或者通过使用完全不同的组织来完成整个事情。
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.
如果insid的论点循环有固定类型,那么也许你可以用
来获取函数的引用(一次)
循环外的
。
这就像Objective-C中的methodForSelector。
-
Brian Gough
Network Theory Ltd,
发布Python手册--- http://www.network-theory.co.uk/
Avoding map()可能有所帮助:
元组([类型(a)for a args])
使用生成器表达式(不是它们在2.4?)可能会也可能不会
help:
元组(对于a args类型(a))
您可以编写一个小扩展来执行此操作,而无需所有
Python函数调用。
来自Python.h的
cdef extern:
extern int PyTuple_Check(object)
extern对象PyTuple_New(int)
extern int PyTuple _GET_SIZE(对象)
extern void * PyObject_Type(void *)
extern void PyTuple_SET_ITEM(object,int,void *)
extern void * PyTuple_GET_ITEM(object,int)
def maptype(i):
如果不是PyTuple_Check(i):引发TypeError
cdef int l
cdef int j
l = PyTuple_GET_SIZE(i)
o = PyTuple_New(l)
来自j 0< = j< l:
PyTuple_SET_ITEM(o,j,PyObject_Type(PyTuple_GET_ITEM(i,j)))
返回o
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(object)
extern object PyTuple_New(int)
extern int PyTuple_GET_SIZE(object)
extern void *PyObject_Type(void*)
extern void PyTuple_SET_ITEM(object, int, void*)
extern void *PyTuple_GET_ITEM(object, int)
def maptype(i):
if not PyTuple_Check(i): raise TypeError
cdef int l
cdef int j
l = PyTuple_GET_SIZE(i)
o = PyTuple_New(l)
for j from 0 <= j < l:
PyTuple_SET_ITEM(o, j, PyObject_Type(PyTuple_GET_ITEM(i, j)))
return o
print maptype.maptype(("",0,0.0,0L,str,int,type))
print maptype.maptype(("", 0, 0.0, 0L, str, int, type))
(< type''str''>,< type''int''>,< type''flo''>,< type''long'' >,< type''type''>,< type''type''>,< type''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);来自maptype导入maptype''''maptype(s)''
100000循环,最佳3:2.41 usec每循环
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
这篇关于优化多个调度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!