Python的内存视图的底层机制
Underlying mechanism of Python's memoryview
Python 的内存视图据说不会在切片时复制数据。已完成许多基准测试,其中一些是针对 Whosebug、"prooving" 这种行为。
在试图打扰他们时,我遇到了一个我无法解释的奇怪行为:
>>> arr = bytearray(range(0,15))
>>> mem = memoryview(arr)
>>> mem[5:15] = mem[0:10]
>>> arr
bytearray(b'\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04\x05\x06\x07\x08\t')
一方面,memoryview "does not"复制数据。另一方面,这非常有效!
虽然我很高兴它 "worked",但我对它的工作原理感到难过。嗯...因为它不应该。
如果 Python 有一个 1 个字符的缓冲区,结果应该是这样的:
bytearray(b'\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04')
基本上,写第5个字的时候,应该是重叠读取前面写的第1个字。这种天真的方法的一个例子:
>>> for i in range(10):
... m[i+5] = m[i]
>>> a
bytearray(b'\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04')
我尝试将 memoryview 的大小增加到很大,但它仍然有效,这意味着 python 在后台复制数据,渲染 memoryview 对象毫无意义。
这里有什么地方我错了吗?有什么解释吗?那么memoryview是如何工作的呢?
if (dptr + size < sptr || sptr + size < dptr)
memcpy(dptr, sptr, size); /* no overlapping */
else
memmove(dptr, sptr, size);
memmove
被指定为对于重叠的源和目标是安全的。它如何确保安全因情况和实施而异,但一种技术是从右到左而不是从左到右工作,如果从左到右会覆盖尚未复制的数据。
Python 的内存视图据说不会在切片时复制数据。已完成许多基准测试,其中一些是针对 Whosebug、"prooving" 这种行为。
在试图打扰他们时,我遇到了一个我无法解释的奇怪行为:
>>> arr = bytearray(range(0,15))
>>> mem = memoryview(arr)
>>> mem[5:15] = mem[0:10]
>>> arr
bytearray(b'\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04\x05\x06\x07\x08\t')
一方面,memoryview "does not"复制数据。另一方面,这非常有效!
虽然我很高兴它 "worked",但我对它的工作原理感到难过。嗯...因为它不应该。
如果 Python 有一个 1 个字符的缓冲区,结果应该是这样的:
bytearray(b'\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04')
基本上,写第5个字的时候,应该是重叠读取前面写的第1个字。这种天真的方法的一个例子:
>>> for i in range(10):
... m[i+5] = m[i]
>>> a
bytearray(b'\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04\x00\x01\x02\x03\x04')
我尝试将 memoryview 的大小增加到很大,但它仍然有效,这意味着 python 在后台复制数据,渲染 memoryview 对象毫无意义。
这里有什么地方我错了吗?有什么解释吗?那么memoryview是如何工作的呢?
if (dptr + size < sptr || sptr + size < dptr)
memcpy(dptr, sptr, size); /* no overlapping */
else
memmove(dptr, sptr, size);
memmove
被指定为对于重叠的源和目标是安全的。它如何确保安全因情况和实施而异,但一种技术是从右到左而不是从左到右工作,如果从左到右会覆盖尚未复制的数据。