如何在Cython中声明2D列表 [英] How to declare 2D list in Cython

查看:127
本文介绍了如何在Cython中声明2D列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编译这种代码:

I'm trying to compile this kind of code:

def my_func(double c, int m):
    cdef double f[m][m]

    f = [[c for x in range(m)] for y in range(m)]
    ...

会引发:

Error compiling Cython file:
------------------------------------------------------------
def grow(double alpha, double beta, double gamma, int m, int s):
    cdef double f[m][m]
                     ^
------------------------------------------------------------
test.pyx:6:22: Not allowed in a constant expression

之后,我假设我不能在指定的位置使用变量,而是尝试使用数值:

after which I assume I can't use variable at the pointed place and I try with numeric value:

def my_func(double c, int m):
    cdef double f[500][500]

    f = [[c for x in range(500)] for y in range(500)]
    ...

但是我得到:

Error compiling Cython file:
------------------------------------------------------------
    f = [[beta for x in range(500)] for y in range(500)]
     ^
------------------------------------------------------------
test.pyx:13:6: Assignment to non-lvalue 'f'

因此,我想知道如何在cython代码中声明和制作2D列表。我在谷歌搜索 cython 2D列表的文档中找不到这种示例

So, I'm wondering how to declare and make 2D list in cython code. I couldn't find this kind of example in documentation of googling for "cython 2D list"

推荐答案

cdef double f[500][500]

这是宣告C数组为500 C 500个双打的数组。那是500 * 500的打包双精度值(在这种情况下,除非在Cython上做一些时髦的事情,否则存储在堆栈上)没有任何间接访问,这有助于提高性能和缓存利用率,但显然增加了严格的限制。也许您想这样做,但是您应该学习足够的C知识,然后才知道这意味着什么。顺便说一句,一个限制是该大小必须是一个编译时常数(取决于C版本; C99和C10允许它),这就是第一个错误消息的含义。

This is declaring a C array of 500 C arrays of 500 doubles. That's 500 * 500 packed double values (stored on the stack in this case, unless Cython does something funky) without any indirection, which aids performance and cache utilization, but obviously adds severe restrictions. Maybe you want this, but you should learn enough C to know what that means first. By the way, one restriction is that the size must be a compile-time constant (depending on the C version; C99 and C10 allow it), which is what the first error message is about.

如果确实使用数组,则不会像以前那样初始化 f ,因为这没有任何意义。 f 已经是500x500的双变量,并且不能将数组作为一个整体分配给它(这是后者的错误消息试图告诉您的内容)。特别是,列表理解会创建一个成熟的Python列表对象(也可以从Cython中使用,请参见下文),其中包含成熟的盒装 Python对象( float 对象, 在这种情况下)。列表与C数组不兼容。使用嵌套的 for 循环进行项目分配以进行初始化。最后,这样的数组需要500 * 500 * 8字节,几乎是2 MiB。在某些系统上,它比整个堆栈大,而在所有其他系统上,它占堆栈的很大部分,这是个坏主意。您应该对该数组进行堆分配。

If you do use arrays, you don't initialize f the way you did, because that doesn't make any sense. f is already 500x500 double variables, and arrays as a whole can't be assigned to (which is what the latter error message is trying to tell you). In particular, list comprehension creates a fully-blown Python list object (which you could also use from Cython, see below) containing fully-blown "boxed" Python objects (float objects, in this case). A list is not compatible with a C array. Use a nested for loop with item assignment for the initialization. Lastly, such an array takes 500 * 500 * 8 byte, which is almost 2 MiB. On some systems, that's larger than the entire stack, and on all other systems, it's such a large portion of the stack that it's a bad idea. You should heap-allocate that array.

如果您使用Python列表,请注意在性能和内存使用方面不会有太多改进(假设您的代码会多数情况下都在处理该列表),尽管您可能会获得一些方便。您可以不使用 cdef ,或使用 list 作为类型(对象也应该工作,但是您从中什么也得不到,所以您最好忽略它。)

If you use a Python list, be warned that you won't get much improvement in performance and memory use (assuming your code will mostly be manipulating that list), though you may gain back some convenience in return. You could just leave off the cdef, or use list as the type (object should work too, but you gain nothing from it, so you might as well omit it).

NumPy数组可能更快,更多的内存-高效,更易于使用。如果您可以根据NumPy的运算实现算法中性能至关重要的部分,则可以完全不使用Cython 获得所需的加速。

A NumPy array may be faster, more memory-efficient, and more convenient to use. If you can implement the performance-critical parts of your algorithm in terms of NumPy's operations, you may gain the desired speedup without using Cython at all.

这篇关于如何在Cython中声明2D列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆