大编辑:
================
为了清楚起见,我删除了旧结果并用更新的结果替换它。问题还是一样:我是否正确地同时使用了 Cython 和 Numba,以及可以对代码进行哪些改进? (我有一个更新更简单的临时 IPython 笔记本,其中包含所有代码和结果 here)
1)
我想我明白了为什么最初 Cython、Numba 和 CPython 之间没有区别:这是因为我喂了它们
numpy 数组作为输入:
x = np.asarray([x_i*np.random.randint(8,12)/10 for x_i in range(n)])
代替列表:
x = [x_i*random.randint(8,12)/10 for x_i in range(n)]
使用 Numpy 数组作为数据输入的基准测试
使用 Python 列表作为输入的基准测试
2)
我用显式循环替换了 zip()
函数,但是,它并没有太大的区别。代码将是:
CPython
def py_lstsqr(x, y):
""" Computes the least-squares solution to a linear matrix equation. """
len_x = len(x)
x_avg = sum(x)/len_x
y_avg = sum(y)/len(y)
var_x = 0
cov_xy = 0
for i in range(len_x):
temp = (x[i] - x_avg)
var_x += temp**2
cov_xy += temp*(y[i] - y_avg)
slope = cov_xy / var_x
y_interc = y_avg - slope*x_avg
return (slope, y_interc)
赛通
%load_ext cythonmagic
%%cython
def cy_lstsqr(x, y):
""" Computes the least-squares solution to a linear matrix equation. """
cdef double x_avg, y_avg, var_x, cov_xy,\
slope, y_interc, x_i, y_i
cdef int len_x
len_x = len(x)
x_avg = sum(x)/len_x
y_avg = sum(y)/len(y)
var_x = 0
cov_xy = 0
for i in range(len_x):
temp = (x[i] - x_avg)
var_x += temp**2
cov_xy += temp*(y[i] - y_avg)
slope = cov_xy / var_x
y_interc = y_avg - slope*x_avg
return (slope, y_interc)
数巴
from numba import jit
@jit
def numba_lstsqr(x, y):
""" Computes the least-squares solution to a linear matrix equation. """
len_x = len(x)
x_avg = sum(x)/len_x
y_avg = sum(y)/len(y)
var_x = 0
cov_xy = 0
for i in range(len_x):
temp = (x[i] - x_avg)
var_x += temp**2
cov_xy += temp*(y[i] - y_avg)
slope = cov_xy / var_x
y_interc = y_avg - slope*x_avg
return (slope, y_interc)
最佳答案
这是我认为 Numba 正在发生的事情:
Numba 适用于 Numpy
数组。没有其他的。其他一切都与 Numba
无关。
zip
返回任意项目的迭代器,Numba 看不到它。因此 Numba 不能做太多编译。
使用 for i in range(...)
遍历索引可能会产生更好的结果并允许更强的类型推断。
关于python - 与 CPython 相比,Numba 和 Cython 没有显着提高性能,也许我使用不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23550483/