用Python高效处理大型二进制文件

3
我正在阅读每个大小为150,000 kb的二进制文件,其中包含大约3,000个结构化的二进制消息,我正在尝试找出最快的处理方法。在每个消息中,我只需要实际读取大约30行数据。这些消息有标头,可以让我跳转到特定部分并找到我需要的数据。
我正在尝试找出是更有效率:解压整个消息(每个50 kb),从结果元组中提取我不实际需要的许多数据,还是使用seek来获取我需要的每个消息中的每一行数据并解压这30行数据之一?或者,这是否更适合于mmap?

你说的“30行”是什么意思?数据是二进制的,所以“行”这个概念并没有太多意义。你能用每条消息的百分比来表达吗?另外,除非百分比接近100%或0%,否则你可能需要进行性能分析才能得到有用的答案。 - bnaecker
抱歉,你是对的,那一点也不清楚。三十个8字节的二进制段。 - AEvers
他们遵循一套结构,尽管消息在各个文件之间的大小是一致的,但它们可能因文件而异。我的计划是读取消息头来确定大小并构建一个格式化字符串来解包整个消息,然后从元组中提取数据。或者,我可以使用消息头找出需要跳过多少字节才能到达想要读取的消息部分,然后我可以解包这个单独的二进制数据以检索变量。 - AEvers
我只是不确定通过跳过消息来解包30个整数是否比单个解包操作解包几百个整数更慢。 - AEvers
一条消息相当大(50Kb),因此像内存映射文件然后寻找(索引)到每个消息的位置是一个好主意。但是,只有当您想要提取的信息集中在消息的某个区域时,这才真正对您有益。如果它们均匀分布在消息中,那么帮助不大。而且不是几百个整数,应该是几千个,对吧? 50Kb / 8bytes约为6K个整数。除非我漏掉了什么。 - bnaecker
显示剩余3条评论
1个回答

1
寻找50kB以内的内容可能不值得,因为系统调用是昂贵的。相反,将每个消息读入一个字节,并使用切片“查找”所需的偏移量并获取正确数量的数据。最好将字节包装在memoryview中以避免复制,但对于小的单独读取来说,这可能并不重要。如果可以使用memoryview,则一定要尝试使用mmap,它在整个文件上公开了类似的接口。如果您正在使用struct,则其unpack_from可以在不包装或复制的情况下在bytes或mmap中查找。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接