Cython:优化原生 Python 内存视图



我有一个函数(来自外部Python库(,它返回一个我想在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 *'

这个由@CodeSurgeon链接的答案是可能的。但是,从 Cython 0.28 开始,我们有了更简洁的方法 - 类型化的只读内存视图:

%%cython
mv = memoryview(b'1234')
cdef const unsigned char[:] tmv=mv  #"const" is possible since Cython 0.28

显然,您只能从此内存视图中读取(这是一件好事(,并且不涉及复制。

你也可以说:但这unsigned char而不是char!没错 - 这也是一件好事:bytesunsigned chars和类型化内存的全部意义在于您没有混淆类型!

我认为链接解决方案有点危险的另一个原因 - 你有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'我们应该为有趣的结果和快乐的调试做好准备......

总的来说,这是一个不费吹灰之力的事情:坚持类型化内存视图,保证类型和恒常性安全。

相关内容

  • 没有找到相关文章

最新更新