Имея 2 функции с эквивалентностью алгоритма в обеих сторонах, в c ++ cpp_func1 (обернутый цинтоном) и в cython cython_func1 , быть Основное различие между ними, в котором функция C ++ работает с векторами, и функция цинтона работает с массивом Numpy и MemoryViews, и делая вызовы функций из Python с массивом Numpy из 100 000 элементов, затем при сравнении о времени выполнения, измеренные времена скажем, что вызовы к функции CPP_FUNC1 обернутая функция примерно в 4 раза медленнее в лучшем случае (пожалуйста Посмотрите, как измерить максимальное использование памяти во время каждого выполнения, и если предварительные результаты являются правильными, то вызовы к функции CPP_FUNC1 обернутая функция показывают гораздо более высокое использование памяти (более чем в 3 раза выше, если результаты верны) .
До сих пор реализация cython cython_func1 была той, которая имеет лучшие результаты производительности, и любые предложения по улучшению приветствуются (пока нет, нет Параллелизация цинтона еще протестирована), но о реализации обертки c ++ cpp_func1 с цинтоном, вероятно, мне не хватает важных оптимизаций, и этот вопрос в основном об этом, о том, как у него может быть лучшая производительность . < /p>
Целью сравнения состоит в том, чтобы сравнивать с обеих сторон алгоритм о циклах и контейнерах с приблизительной эквивалентностью, стремясь работать с контейнерами, чтобы избежать копий контейнеров , чтобы быть высокоэффективным при работе с большими контейнерами.cpp_func2 и cython_func2 ) также с петлями и контейнерами, среднее время выполнения в функции CPP_FUNC2 обернутая функция было в 24 раза медленнее, чем цинтона эквивалентная функция .
cython_funcs.pyx:
def cython_func1(double[::1] arr):
cdef int n, m
cdef int window = 5
cdef int len = arr.shape[0] - window + 1
cdef double min_var = 0.0
cdef double max_var = 0.0
cdef double diff_var = 0.0
arr_result = np.zeros(len, dtype=np.double)
cdef double[::1] arr_result_view = arr_result
for n in range(len):
diff_var = 0.0
for m in range(n, (n + window)):
if (m == n):
min_var = arr[m]
max_var = arr[m]
else:
if (arr[m] < min_var):
min_var = arr[m]
elif (arr[m] > max_var):
max_var = arr[m]
diff_var = max_var - min_var
arr_result_view[n] = diff_var
return arr_result
ythonhon_funcs_setup.py:
# Compilation command (CMD):
# python cython_funcs_setup.py build_ext --inplace
from setuptools import setup
from Cython.Build import cythonize
import numpy
setup(
ext_modules = cythonize("cython_funcs.pyx"),
include_path = [numpy.get_include()]
)
cpp_funcs.cpp:
std::vector cpp_func1(const std::vector &vec) {
int window = 5;
int len = vec.size() - window + 1;
double min_var = 0.0;
double max_var = 0.0;
double diff_var = 0.0;
std::vector vec_result(len, 0.0);
for (int n = 0; n < len; n++) {
diff_var = 0.0;
for (int m = n; m < (n + window); m++) {
if (m == n) {
min_var = vec[m];
max_var = vec[m];
}
else {
if (vec[m] < min_var) {
min_var = vec[m];
}
else if (vec[m] > max_var) {
max_var = vec[m];
}
}
}
diff_var = max_var - min_var;
vec_result[n] = diff_var;
}
return vec_result;
}
cpp_funcs.h:
#ifndef CPP_FUNCS_H
#define CPP_FUNCS_H
#include
#include
using namespace std;
std::vector cpp_func1(const std::vector &vec);
#endif
cpp_funcs_wrapper.pyx:
import numpy as np
from libcpp.vector cimport vector
#cdef extern from "cpp_funcs.cpp":
# pass
cdef extern from "cpp_funcs.h":
vector[double] cpp_func1(vector[double] &vec)
def cpp_func1_cython(vector[double] &vec):
return cpp_func1(vec)
cpp_funcs_setup.py:
# Compilation command (CMD):
# python cpp_funcs_setup.py build_ext --inplace
from setuptools import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy
extensions = [Extension("cpp_funcs_wrapper",
["cpp_funcs_wrapper.pyx", "cpp_funcs.cpp"],
language="c++",
#extra_link_args=["-lz"]
)]
setup(
name="cpp_funcs_wrapper",
ext_modules=cythonize(extensions),
include_path = [numpy.get_include()]
)
вызовы из Python :
import cython_funcs
import cpp_funcs_wrapper
import numpy as np
import timeit
arr = np.random.uniform(1, 100000, 100_000)
var1 = timeit.timeit("cython_funcs.cython_func1(arr)", globals=globals(), number=100)
print(f"Average time = {((var1/100) * 1000)} ms.")
var2 = timeit.timeit("cpp_funcs_wrapper.cpp_func1_cython(arr)", globals=globals(), number=100)
print(f"Average time = {((var2/100) * 1000)} ms")
< /code>
Обновление 1 < /strong>:
Как указано в комментариях ниже, я пытался включить Флаги об оптимизации компиляции в файле настройки цинтона, надеясь, что обернутая функция C ++ работала еще более эффективной, чем версия Pure Cython, но часть времени произошла, часть флагов была проигнорирована, а другая часть произошла, которая была ошибкой компиляции Полем Когда флаги/флаги были проигнорированы, терминал показал сообщение на пути: «Незначенный вариант»/o2 '; игнорируется », завершив сборник, но по мере того, как часть оптимизации была проигнорирована, то результаты эталона сохранялись в том же диапазоне ( Нет единого улучшения):
О флагах я попробовал с более чем 10 вариантами, но я помесчу одну из них, чтобы иметь общую идею:
sstrong>cpp_funcs_o_setup.py:
'''
The next is not the current Cython setup file.
Reference about the next syntax, format, etc:
https://cython.readthedocs.io/en/stable ... ompilation
All the attempts about compilation optimizations were
only working with the Cython setup file, i.e. not
modifying anything in the command for the compilation.
Compilation command (CMD):
python cpp_funcs_O_setup.py build_ext --inplace
'''
from setuptools import Extension, setup
from Cython.Build import cythonize
import sys
#Also including the part about NumPy when needed.
if sys.platform.startswith("win"):
compile_args = '/O1'
else:
compile_args = '-O1'
ext_modules = [
Extension(
"cpp_funcs_wrapper",
sources=["cpp_funcs_wrapper.pyx", "cpp_funcs.cpp"],
language="c++",
extra_compile_args=[compile_args], # Also for example trying with the next directly here: '/O1', '/O2', '/O3', '/Ofast' '-O1', '-O2', '-O3', ...
extra_link_args=[compile_args],
),
# Also trying to comment/omit the next `Extension` part, and other variants.
Extension(
"cpp_funcs_wrapper",
sources=["cpp_funcs_wrapper.pyx", "cpp_funcs.cpp"],
language="c++",
extra_compile_args=[compile_args],
extra_link_args=[compile_args],
)
]
setup(
name='cpp_funcs_wrapper',
ext_modules=cythonize(ext_modules),
)
Подробнее здесь: https://stackoverflow.com/questions/793 ... -than-equi
Функция C ++ (векторы), обернутые цинтоном, примерно в 4 раза медленнее, чем эквивалентная функция цинтона (Numpy Mastry ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение