Cython:优化原生 Python 内存视图
Cython: optimize native Python memoryview
我有一个函数(来自外部 Python 库)returns 我想在 Cython 中处理的 memoryview
对象。
有没有办法将其转换为类型化的字节内存视图(无副本)以提高效率?我该怎么做?这不起作用:
mv = memoryview(b'1234')
cdef char[:] *tmv
tmv = mv
^
------------------------------------------------------------
/home/me/.cache/ipython/cython/_cython_magic_f9f608355444e2d6828580906623cea8.pyx:3:6: Cannot convert Python object to '__Pyx_memviewslice *'
This answer linked by @CodeSurgeon is a possibility to do it. However, since Cython 0.28 we have a much cleaner way - the typed read-only 记忆浏览:
%%cython
mv = memoryview(b'1234')
cdef const unsigned char[:] tmv=mv #"const" is possible since Cython 0.28
显然你只能从这个内存视图中读取(这是一件好事)并且不涉及复制。
您也可以说:但这是 unsigned char
而不是 char
!是的 - 这也是一件好事:bytes
是 unsigned char
和类型化内存视图的全部要点,你没有混淆类型!
另一个我认为链接解决方案有点危险的原因 - 你拥有 C 的全部力量来搬起石头砸自己的脚,因为它抛弃了类型和常量。参见示例:
%%cython
def bad_things(a):
cdef const unsigned char[:] safe=a
cdef char *unsafe=<char *> &safe[0] #who needs const and types anyway?
unsafe[0]=52 #replace through `4`
现在:
>>> A=b'a'
>>> bad_things(A)
>>> print(A) #take it Python - I pwned your immutability!
b'4'
>>> print(b'a')
b'4'
>>> #Help! What are you doing Python?
因为 Python 有一个小字符串池,它们是不可变的(或者 Python 认为如此),并且我们已经将 b'a'
链接到的对象更改为 b'4'
我们应该为有趣的结果和愉快的调试做好准备...
总的来说,这是一个明智的选择:坚持保证类型和常量安全的类型化内存视图。
我有一个函数(来自外部 Python 库)returns 我想在 Cython 中处理的 memoryview
对象。
有没有办法将其转换为类型化的字节内存视图(无副本)以提高效率?我该怎么做?这不起作用:
mv = memoryview(b'1234')
cdef char[:] *tmv
tmv = mv
^
------------------------------------------------------------
/home/me/.cache/ipython/cython/_cython_magic_f9f608355444e2d6828580906623cea8.pyx:3:6: Cannot convert Python object to '__Pyx_memviewslice *'
This answer linked by @CodeSurgeon is a possibility to do it. However, since Cython 0.28 we have a much cleaner way - the typed read-only 记忆浏览:
%%cython
mv = memoryview(b'1234')
cdef const unsigned char[:] tmv=mv #"const" is possible since Cython 0.28
显然你只能从这个内存视图中读取(这是一件好事)并且不涉及复制。
您也可以说:但这是 unsigned char
而不是 char
!是的 - 这也是一件好事:bytes
是 unsigned char
和类型化内存视图的全部要点,你没有混淆类型!
另一个我认为链接解决方案有点危险的原因 - 你拥有 C 的全部力量来搬起石头砸自己的脚,因为它抛弃了类型和常量。参见示例:
%%cython
def bad_things(a):
cdef const unsigned char[:] safe=a
cdef char *unsafe=<char *> &safe[0] #who needs const and types anyway?
unsafe[0]=52 #replace through `4`
现在:
>>> A=b'a'
>>> bad_things(A)
>>> print(A) #take it Python - I pwned your immutability!
b'4'
>>> print(b'a')
b'4'
>>> #Help! What are you doing Python?
因为 Python 有一个小字符串池,它们是不可变的(或者 Python 认为如此),并且我们已经将 b'a'
链接到的对象更改为 b'4'
我们应该为有趣的结果和愉快的调试做好准备...
总的来说,这是一个明智的选择:坚持保证类型和常量安全的类型化内存视图。