我正在使用Python与一个使用cppyy的库一起使用Python来访问大量的C++函数。但是,对cppyy方法的调用需要很长时间,在Python中循环库调用意味着开销成为一个严重的问题。下面是我的一个例子:
import ROOT # Library based on cppyy
def some_function():
for i in range(10_000_000):
ROOT.some_method(i) # A little bit of overhead * 10_000_000 is a lot of overhead如果我在C++中直接使用根库,这段代码会非常快,但是Python非常慢。
在编译版本不使用Python运行时(如numba nopython=True)的情况下,是否有一种方法可以将其编译为快速运行?
发布于 2021-04-01 16:58:14
在some_method中只需做很少的工作就可以让日常开销变得重要.请注意,还存在方法查找的开销(即ROOT.位),如果cppyy开销不是可以忽略的,Python本身中的迭代器协议也是不可忽略的(给空循环计时,我发现它占总开销的20% )。
为了避免所有这些,如果这是一个紧密的内环,只需反转它并在C++中运行它。例如,比较以下几点:
import cppyy
import time
N = 10000000
cppyy.cppdef("""\
void cppmethod(int i) {
/* empty */
}""")
f = cppyy.gbl.cppmethod
ts = time.perf_counter()
for i in range(N):
f(i)
te = time.perf_counter()-ts
print("python loop:", te)
cppyy.cppdef("""\
template<typename T>
void call_cppmethod(T f, int N) {
for (int i = 0; i < N; ++i) f(i);
}""")
ts = time.perf_counter()
cppyy.gbl.call_cppmethod(f, N)
te = time.perf_counter()-ts
print("callback loop:", te)在我的笔记本电脑上,回调比Python循环快100倍。但是,如果我在cppmethod上做了什么,例如。调用三角函数时,差异已经下降到10倍(同样,一个很好的块只是python循环)。
可以肯定的是,上面使用的回调模板在cppyy中起作用。然而,根包含一个已经过时的分叉cppyy。在那里,您不能使用模板,必须对函数类型进行显式说明:
cppyy.cppdef("""\
void call_cppmethod(void (*f)(int), int N) {
for (int i = 0; i < N; ++i) f(i);
}""")如果/当ROOT更新他们的分叉时,这个问题可能会在将来的某个时候消失,但现在情况就是这样。
https://stackoverflow.com/questions/66906591
复制相似问题