列表项类型应该在Cython中定义吗?
如果我把一个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列表更好么?
1 个回答
19
在Cython中,你不需要强制声明任何东西。声明数据类型通常会帮助提高性能。之所以说通常,是因为如果你声明了类型,但又不使用它们,可能会导致类型检查和打包解包的开销。想要确定效果,最好的办法就是测量一下。
要声明列表的类型,只需在开头加上cdef float value
,然后在循环中使用value = example_list[i]
。
那么,应该使用列表还是numpy数组呢?数组是一种统一的数据容器。这意味着你可以把它声明为float32_t
,这样Cython就能以C语言的速度来处理它(访问速度更快,因为它在内存中是连续的并且有固定的步长)。另一方面,如果你需要改变大小,使用列表可能更好(或者在需要大量使用时,考虑使用libcpp.vector
)。所以答案是要看你具体做什么,但在大多数情况下,数组会更好。
公平地说,你还得考虑数据的存放方式。如果你所有的数据都在列表中,那么使用数组的函数可能会更快,但list -> array -> f_array -> array -> list
的速度可能会比list -> f_list -> list
慢。如果你不在意,作为一个经验法则,当长度是固定的时候用数组,其他情况下用列表。另外,注意对于大量数据,numpy数组在内存占用上更轻。