我还是不明白memoryview的意义

I still don't understand the point of memoryview

我通读了问题和答案或 What exactly is the point of memoryview in Python。我还是没看出来。

答案中的示例乍一看似乎合乎逻辑,但是当我构造第三个测试用例时,我在其中按索引扫描 bytes 对象,它与 memoryview 一样快。

import time


# Scan through a bytes object by slicing
for n in (100000, 200000, 300000, 400000):
    data = b'x' * n
    start = time.time()
    b = data
    while b:
        b = b[1:]
    print('bytes sliced  ', n, time.time() - start)

# Scan through a bytes object with memoryview
for n in (100000, 200000, 300000, 400000):
    data = b'x' * n
    start = time.time()
    b = memoryview(data)
    while b:
        b = b[1:]
    print('memoryview    ', n, time.time() - start)

# Scan through a bytes object by index
for n in (100000, 200000, 300000, 400000):
    data = b'x' * n
    start = time.time()
    b = data
    for i in range(n):
        b = b[i+1:]
    print('bytes indexed ', n, time.time() - start)

输出:

bytes sliced   100000 0.16396498680114746
bytes sliced   200000 0.6180000305175781
bytes sliced   300000 1.541727066040039
bytes sliced   400000 2.8526365756988525
memoryview     100000 0.02300119400024414
memoryview     200000 0.04699897766113281
memoryview     300000 0.0709981918334961
memoryview     400000 0.0950019359588623
bytes indexed  100000 0.027998924255371094
bytes indexed  200000 0.05700063705444336
bytes indexed  300000 0.08800172805786133
bytes indexed  400000 0.1179966926574707

其中一个论点是,您可以简单地将 memoryview 对象传递给 struct.unpack。但是你绝对可以对字节对象做同样的事情。在我的理解中,它归结为与 memoryview 最终也必须复制切片相同。

如果你不做傻事,坚持使用字节似乎简单多了。

您的前两个基准测试基本上从左边蚕食一个字节,直到什么都没有。

对于bytes示例,这会复制N份,对于内存视图,永远不会有副本,只是调整视图的长度

你的最后一个例子一点也不相似,你不是蚕食一个字节,而是蚕食越来越多的字节(b[1:] b[2:] b[3:]) -- 最终字符串用完了,你正在切割一个空字符串(更准确地说是 i * (i + 1) / 2 > n 时)。例如,对于 100,000 字节的序列,您将在 446 次迭代后执行空操作。