我试图测量 python 字典、cythonized python 字典和 cythonized cpp std::unordered_map 之间的性能,仅执行 init 过程。如果编译 cythonized cpp 代码,我认为它应该比纯 python 版本更快。我使用 4 种不同的场景/符号选项进行了测试:
- 使用 std::unordered_map 的 Cython CPP 代码和Cython 书籍符号(定义一对并使用插入方法)
- 使用 std::unordered_map 和 python 表示法的 Cython CPP 代码(map[key] = value)
- 使用 python 字典的 Cython 代码(类型化代码)(map[key] = value)
- 纯Python代码
我期待看到 cython 代码如何优于纯 python 代码,但在这种情况下没有任何改进。可能是什么原因?我正在使用 Cython-0.22、python-3.4 和 g++-4.8。
我使用 timeit 得到了这个执行时间(秒):
- Cython CPP 书本符号 -> 15.696417249999968
- Cython CPP python 表示法 -> 16.481350984999835
- Cython python 表示法 -> 18.585355018999962
- 纯Python-> 18.162724677999904
代码在这里,您可以使用它:
cython -a map_example.pyx
python3 setup_map.py build_ext --inplace
python3 use_map_example.py
地图示例.pyx
from libcpp.unordered_map cimport unordered_map
from libcpp.pair cimport pair
cpdef int example_cpp_book_notation(int limit):
cdef unordered_map[int, int] mapa
cdef pair[int, int] entry
cdef int i
for i in range(limit):
entry.first = i
entry.second = i
mapa.insert(entry)
return 0
cpdef int example_cpp_python_notation(int limit):
cdef unordered_map[int, int] mapa
cdef pair[int, int] entry
cdef int i
for i in range(limit):
mapa[i] = i
return 0
cpdef int example_ctyped_notation(int limit):
mapa = {}
cdef int i
for i in range(limit):
mapa[i] = i
return 0
setup_map.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
import os
os.environ["CC"] = "g++"
os.environ["CXX"] = "g++"
modules = [Extension("map_example",
["map_example.pyx"],
language = "c++",
extra_compile_args=["-std=c++11"],
extra_link_args=["-std=c++11"])]
setup(name="map_example",
cmdclass={"build_ext": build_ext},
ext_modules=modules)
use_map_example.py
import map_example
C_MAXV = 100000000
C_NUMBER = 10
def cython_cpp_book_notation():
x = 1
while(x<C_MAXV):
map_example.example_cpp_book_notation(x)
x *= 10
def cython_cpp_python_notation():
x = 1
while(x<C_MAXV):
map_example.example_cpp_python_notation(x)
x *= 10
def cython_ctyped_notation():
x = 1
while(x<C_MAXV):
map_example.example_ctyped_notation(x)
x *= 10
def pure_python():
x = 1
while(x<C_MAXV):
map_a = {}
for i in range(x):
map_a[i] = i
x *= 10
return 0
if __name__ == '__main__':
import timeit
print("Cython CPP book notation")
print(timeit.timeit("cython_cpp_book_notation()", setup="from __main__ import cython_cpp_book_notation", number=C_NUMBER))
print("Cython CPP python notation")
print(timeit.timeit("cython_cpp_python_notation()", setup="from __main__ import cython_cpp_python_notation", number=C_NUMBER))
print("Cython python notation")
print(timeit.timeit("cython_ctyped_notation()", setup="from __main__ import cython_ctyped_notation", number=C_NUMBER))
print("Pure python")
print(timeit.timeit("pure_python()", setup="from __main__ import pure_python", number=C_NUMBER))