在Python中预初始化地址而无需迭代的快速方法?

问题描述 投票:0回答:1

我有由数据包组成的二进制文件,其序列化如下:

[Length][Payload][Length][Payload][Length][Payload]

长度始终为 4 个字节,并且值是可变的,没有特定的模式。长度值包括

[Length]
本身的 4 个字节。我需要提取文件中每个
[Length]
的第一个字节的字节位置。例如:

00 00 02 00 FF FF FF FF FF ...
00 01 3C E5 FF FF FF FF FF ...
00 00 A5 90 FF FF FF FF FF ...
^
Need to save all these indexes

这可以工作,但速度很慢,因为每个文件有超过 100k 的数据包:

data = mmap.mmap(filename.fileno(), 0, access=mmap.ACCESS_READ)
fileSize = os.path.getsize(filename.name)

address = 0
addresses = []

start = time.time()

while address < fileSize:
    pkt_length = bytes2int(data[address:(address + 4)])
    addresses.append(address)
    address += pkt_length

end = time.time()

print(len(addresses))
print(end-start)

我可以用什么来更快地做到这一点?

编辑 2 使用操作系统库

start = time.time()
addresses = []
fp = os.open(fileName, os.O_RDONLY)
while True:
    buf = os.read(fp, 4)
    if not buf:
        break
    size = int.from_bytes(buf, byteorder='big')
    addresses.append(os.lseek(fp, size-4, os.SEEK_CUR))  # -4 cause length already read

end = time.time()
print(len(addresses))
print(end-start)

结果:

45559456
179.0517611503601

编辑1 以下是 4.2GB 文件的性能示例:

45559456
21.271047115325928

RAM 消耗也相当高。

python byte
1个回答
1
投票

您是否尝试过直接读取和查找而不是映射:

while open(...) as fp:
    while True:
        buf = fp.read(4)
        if not buf:
            break
        size = int.from_bytes(buf, byteorder='big')
        size_list.append(size)
        fp.seek(size, os.SEEK_CUR)

只是好奇这是否会更快。

© www.soinside.com 2019 - 2024. All rights reserved.