Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么使用Cython列表比使用Python列表快?_Python_Performance_List_Numpy_Cython - Fatal编程技术网

为什么使用Cython列表比使用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

以下是我的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 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