优化多个调度 [英] Optimizing multiple dispatch

查看:48
本文介绍了优化多个调度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆