如果我将一个python列表发送到cython函数进行迭代,我想要声明列表项的类型是什么?在cython中循环列表的最佳方法是什么?例如:
#Cython function, passed a list of float items
def cython_f(list example_list):
cdef int i
for i in range(len(example_list)):
#Do stuff
#but list item type not defined?
pass
#Alternative loop
cdef j float #declaration of list item type
for j in example_list:
#Do stuff
pass
尝试定义列表项类型是否获得了任何速度?是否最好传递numpy数组而不是python列表?
答案 0 :(得分:18)
在Cython中,您没有义务申报任何内容。声明类型通常有助于提高性能。 通常是因为如果你声明类型,但是不要使用它们,你可能会引发类型检查和打包解压缩。唯一可以确定的方法就是衡量。
要声明列表的类型,只需将其放在cdef float value
的开头,然后放在循环value = example_list[i]
中。
你应该使用list还是numpy数组?数组是统一的数据容器。这意味着您可以将其声明为float32_t
,并且Cython将知道如何以C速度使用它(访问速度更快,因为它保证在内存中连续和跨越)。另一方面,如果要更改大小,则可能更好地使用列表(或者用于非常繁重的使用,可能是libcpp.vector
)。所以答案取决于你做了什么,但在大多数情况下,阵列更好。
公平地说,你必须考虑数据是如何生存的。如果列表中包含所有内容,则使用数组的函数可能会更快,但list -> array -> f_array -> array -> list
可能比list -> f_list -> list
慢。如果您不在乎,根据经验,当长度不变时使用数组并以其他方式列出。另请注意,对于大量数据,numpy数组在内存上更轻。