为什么使用Cython列表比使用Python列表快?
以下是我的Python代码:为什么使用Cython列表比使用Python列表快?,python,performance,list,numpy,cython,Python,Performance,List,Numpy,Cython,以下是我的Python代码: X = [[0] * 1000] * 100 start = time() for x in xrange(100): for i in xrange(len(X)): for j in xrange(len(X[i])): X[i][j] += 1 print time() - start 我的Cython代码是相同的: X = [[0] * 1000] * 100 start = time() for x in
X = [[0] * 1000] * 100
start = time()
for x in xrange(100):
for i in xrange(len(X)):
for j in xrange(len(X[i])):
X[i][j] += 1
print time() - start
我的Cython代码是相同的:
X = [[0] * 1000] * 100
start = time()
for x in xrange(100):
for i in xrange(len(X)):
for j in xrange(len(X[i])):
X[i][j] += 1
print time() - start
输出:
Python成本:2.86秒
赛昂成本:0.41秒
在Python或Cython中有没有其他更快的方法来完成上述操作
更新:有没有办法创建一个2d数组X,其高度索引性能接近C/C++中的数组int X[][]呢
目前,我正在考虑使用Python C API来完成这项工作
还有一件事,numpy数组做同样的事情,但比纯Python和Cython中的list慢70秒
Python:
X = np.zeros((100,1000),dtype=np.int32)
start = time()
for x in xrange(100):
for i in xrange(len(X)):
for j in xrange(len(X[i])):
X[i][j]+=1
如果大量访问数值数组,哪种方法是最好的
在Python或Cython中有没有其他更快的方法来完成上述操作
等效的、更快的代码是:
X = [[100 * 100] * 1000] * 100
在代码中,您将创建一个1000长的零列表,然后创建一个100长的引用列表。现在,在这100个长列表上迭代100次会导致每个位置增加100*100=10000次
如果您希望最终得到100个列表:
请注意,对列表中对象的引用仍然是复制的。为了回答标题中的问题,Cython代码优于Python代码,因为尽管没有cdef来声明变量,但是除了大量额外的C代码来描述Python对象外,还为for循环生成了C代码。为了加快Cython代码的速度,请使用cdef声明整数i、j和x,使它们不再是Python整数:例如cdef int i。您还可以使用Cython,这将进一步提高性能 使用NumPy获得相同结果的快捷方法:
X = np.zeros((100, 1000), dtype=np.int32)
X += 10000
如果您可以帮助它,就永远不要使用带有NumPy数组的for循环。就内存使用而言,它们与列表完全不同。ajcr的答案可能是最快、最简单的答案。您应该首先在cython代码中显式声明变量的数据类型。此外,我将为外部循环创建一个prange,而不是一个简单的范围迭代器。这将激活OpenMP多线程,这可能会进一步加快代码的速度,但我真的怀疑这个解决方案是否能击败numpy实现 你能用numpy显示代码吗?前面的一个问题是关于为什么速度更快以及为速度付出的代价interest@kroolik添加了numpy数组代码numpy如果按预期使用,即通过编写矢量化代码,可以非常快速。您的numpy示例可以简单地写成Z=np.zeros1001000,np.int32;X+=1,甚至更简单,如np.ones100,1000,np.int32,对于我的机器上的就地添加,这应该非常快~85us。如果你发布了你试图优化的实际函数,那么我们很有可能会帮助你编写一个矢量化版本。我一点也不奇怪——实际上,这些代码都没有矢量化!并不是数组容器本身更快,访问单个元素的速度实际上比使用列表慢,而是它允许您一次对多个数组元素应用操作,从而避免在Python中循环元素。为了充分利用numpy,你真的必须停止把数组当作嵌套列表来对待,而要了解向量化操作的概念。谢谢你,kroolik,你的代码是完全正确的。是我的错没有把我的想法说清楚。我想找到一种快速的方法来使用高性能的2d数组。比如C代码中的int a[][]。@LessisAweasome,有什么用途?最通用的一个是您发布的,在Cython中,在内部循环中使用您需要的代码进行双循环。任何更多的优化都可以在考虑特定用例的情况下进行。
base = [100] * 1000
X = [list(base) for _ in xrange(100)]
len(set(map(id, X)))
100
X = np.zeros((100, 1000), dtype=np.int32)
X += 10000