Timing of a C++ function wrapped with cython
我真的不知道如何提出这个问题,但我会尽量保持清醒。
我正在计算来自python的C ++函数调用。 C ++函数包含在cython中。
我目前正在计时cython函数的python调用,我用
问题是,我在C ++中测量的是17.1 ms。
C ++函数声明为此
cython代码只调用C ++类方法。该向量包含大约320k个元素。
我想知道这两个测量时间是否可以这样比较?
如果可以,有什么可以解释这个差距?
如果没有,我应该使用哪种计时工具?
Edit1 :(注释中的链接)两个时序库对于我的用例来说足够精确(我的拱门上的cpp为10e-9,python为10e-6)。
Edit2:添加简化代码来说明我的观点。使用此代码,python调用持续时间(~210ms)是实习生cpp持续时间(~28ms)的8倍。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | // example.cpp #include"example.h" #include <iostream> #include <chrono> std::vector<float> wrapped_function(std::vector<float> array) { auto start = std::chrono::high_resolution_clock::now(); std::vector<float> result; for (int i = 0; i < (int) array.size(); i++) { result.push_back(array[i] / 1.1); } auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<float> duration = end - start; printf("Within duration: %.5f ", duration.count()); return result; } // example.h #ifndef __EXAMPLE_H_ #define __EXAMPLE_H_ #include <vector> std::vector<float> wrapped_function(std::vector<float> array); #endif # example_wrapper.pxd from libcpp.vector cimport vector cdef extern from"example.h": vector[float] wrapped_function(vector[float]) # example_wrapper.pyx from example_wrapper cimport wrapped_function def cython_wrap(array): return wrapped_function(array) # setup.py from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext setup( cmdclass = {"build_ext": build_ext}, ext_modules = [ Extension(name="example_wrapper", sources=["example_wrapper.pyx","example.cpp"], include_dirs=["/home/SO/"], language="c++", extra_compile_args=["-O3","-Wall","-std=c++11"] ) ] ) # test.py import example_wrapper from time import time array = [i for i in range(1000000)] t0 = time() result = example_wrapper.cython_wrap(array) t1 = time() print("Wrapped duration: {}".format(t1 - t0)) |
显然不同之处在于cython开销,但为什么它如此之大?
包裹函数的调用比眼睛更复杂:
1 2 | def cython_wrap(array): return wrapped_function(array) |
正如您所看到的,正在进行大量复制,这解释了您正在观察的开销。
以下是从c ++ - containers转换为python时cython自动应用的一组规则。
另一个问题:您通过值传递向量
你应该通过const-reference传递向量,即
1 | ... wrapped_function(const std::vector<float> &array) |
还有一件事:你返回一个可能被复制的向量,这个复制时间再次不包含在你的c ++ - 时序中。但是,所有现代编译器都应用返回值优化,因此这不是问题。