Cython:我什么时候应该将字符串定义为char *,str或bytes?

问题描述 投票:3回答:2

在Cython + Python 3中定义一个包含字符串的变量类型时,我可以使用(至少):

cdef char* mystring = "foo"
cdef str mystring = "foo"
cdef bytes mystring = "foo"

documentation page on strings对此不清楚 - 它主要是使用char *和字节给出的例子,坦率地说,我很难理解它。

在我的情况下,字符串将来自Python3程序,并假定为unicode。它们将用作dict键和函数参数,但我不会对它们进行进一步的操作。毋庸置疑,我正在努力提高速度。

This question建议在Python2.7和没有Unicode的情况下,键入str会使字符串操作代码运行SLOWER而不是完全不输入。 (但这并不一定与此相关,因为我不会做很多字符串操作。)

每种选择的优点和缺点是什么?

python string python-3.x cython
2个回答
1
投票

如果没有对特定类型进行进一步处理,那么最好不要输入它们,这意味着它们被视为通用的PyObject *

str类型是special case,意思是Python 2上的bytes和Python 3上的unicode

str类型的特殊之处在于它是Python 2中的字节字符串和Python 3中的Unicode字符串

因此,将字符串键入为str并将其作为unicode处理的代码将在python 2中断,其中str表示bytes

如果要将字符串转换为C char*或C ++ std::string,则只需键入字符串。在那里,您将使用str来处理py2 / py3兼容性,以及用于转换为/来自字节和unicode的辅助函数,以便能够转换为char*std::string

键入字符串是为了与C / C ++进行互操作,而不是为了速度。 Cython将自动转换,而不是复制,bytes字符串到char*,例如当它看到类似cdef char* c_string = b_string[:b_len],其中b_stringbytes类型。

OTOH,如果在没有使用该类型的情况下键入字符串,Cython将在不需要导致开销的情况下执行从对象到字节/ unicode的转换。

这可以在生成为Pyx_PyObject_AsStringPyx_PyUnicode_FromString等人的C代码中看到。

一般情况下也是如此 - 经验法则是如果不需要特定类型进行进一步处理/转换,最好不要输入它。 python中的所有内容都是一个对象,因此输入将从通用PyObject*转换为更具体的内容。


0
投票

一些快速测试显示,对于这个特殊情况,只有str声明有效 - 所有其他选项产生错误。由于字符串是在Python3的其他地方生成的,显然需要str类型声明。

是否更快不做任何声明仍然是一个悬而未决的问题。

© www.soinside.com 2019 - 2024. All rights reserved.