【问题标题】:How to improve performance when having a huge list of bytes to be written to file?当有大量字节要写入文件时如何提高性能?
【发布时间】:2017-11-06 17:37:13
【问题描述】:

在 python 中,我有一个庞大的浮点值列表(近 3000 万个值)。我必须将它们中的每一个转换为小端格式的 4 字节值,然后按顺序将它们写入二进制文件。

对于包含数千甚至 100k 数据的列表,我的代码运行良好。但是如果数据增加,处理和写入文件需要时间。我可以使用哪些优化技术来更有效地写入文件?

正如this 博客中所建议的那样,我正在使用字节数组替换所有对文件的小写入。但是,性能还是不能令人满意。

我还尝试了多处理 (concurrent.futures.ProcessPoolExecutor()) 来利用系统中的所有内核,而不是使用单个 CPU 内核。但仍然需要更多时间才能完成执行。

谁能给我更多关于如何提高这个问题的性能(在时间和内存方面)的建议。

这是我的代码:

def process_value (value):
    hex_value =  hex(struct.unpack('<I', struct.pack('<f', value))[0])
    if len(hex_value.split('x')[1]) < 8:
        hex_value = hex_value[:2] + ('0' * (8 - len(hex_value.split('x')[1]))) + hex_value[2:]

    dec1 = int( hex_value.split('x')[1][0] + hex_value.split('x')[1][1], 16)
    dec2 = int(hex_value.split('x')[1][2]+hex_value.split('x')[1][3],16)
    dec3 = int(hex_valur.split('x')[1][4]+hex_value.split('x')[1][5],16)
    dec4 = int(hex_value.split('x')[1][6]+hex_value.split('x')[1][7],16)
    msg = bytearray( [dec4,dec3,dec2,dec1] )
    return msg

def main_function(fp, values):
    msg = bytearray()
    for val in values:
        msg.extend (process_value(val))
    fp.write(msg)

【问题讨论】:

  • 如果您正在编写具有 3000 万个浮点值的代码,您可能需要查看NumPy
  • NumPy 加 mmap 似乎是最快的。
  • 你能给values举个小例子吗?
  • ...这些十六进制的东西到底是怎么回事? struct.pack 输出应该已经是您需要的了。 process_value 中的其他所有内容都是多余的。
  • 这些值类似于 [0.1245332677, -1.5734637835, 1.473683673, ...]

标签: python performance optimization


【解决方案1】:

您可以在写入之前尝试转换所有浮点数,然后一次性写入结果数据:

import struct    

my_floats = [1.111, 1.222, 1.333, 1.444]    

with open('floats.bin', 'wb') as f_output:
    f_output.write(struct.pack('<{}f'.format(len(my_floats)), *my_floats))

对于您拥有的值的数量,您可能需要在大块中执行此操作:

import struct    

def blocks(data, n):
    for i in xrange(0, len(data), n):
        yield data[i:i+n]

my_floats = [1.111, 1.222, 1.333, 1.444]    

with open('floats.bin', 'wb') as f_output:
    for block in blocks(my_floats, 10000):
        f_output.write(struct.pack('<{}f'.format(len(block)), *block))

struct.pack() 的输出应采用正确的二进制格式,以便直接写入文件。该文件必须以二进制模式打开,例如使用wb

【讨论】:

  • 感谢您的回答。分块写入实际上是节省时间和内存。
  • 很高兴它有帮助。完成后,不要忘记单击向上/向下按钮下的灰色勾号,以选择一个答案作为接受的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-09
  • 2021-10-31
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2019-12-21
相关资源
最近更新 更多