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

时间:2018-03-31 06:44:54

标签: python string python-3.x cython

在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而不进行任何键入操作。 (但这并不一定与此相关,因为我不会做很多字符串操作。)

每种选择有哪些优点和缺点?

2 个答案:

答案 0 :(得分:2)

如果没有对特定类型进行进一步处理,那么最好不要输入它们,这意味着它们被视为通用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_string bytes类型为Pyx_PyObject_AsString时。

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

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

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

答案 1 :(得分:0)

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

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