如何优化从RAM到光盘的写入?

2024-09-30 14:31:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些python代码,用于从FPGA的RAM读取数据并将其写入计算机上的磁盘。代码的运行时间是2.56秒。我需要把它降到2秒。你知道吗

mem = device.getNode("udaq.readout_mem").readBlock(16384)
device.dispatch()
ram.append(mem)
ram.reverse()
memory = ram.pop() 
for j in range(16384):
    if 0 < j < 4096:
        f.write('0x%05x\t0x%08x\n' %(j, memory[j]))
    if 8192 < j < 12288:
        f.write('0x%05x\t0x%08x\n' %(j, memory[j]))

Tags: 代码ifdevice计算机时间读取数据mem磁盘
2条回答

让-弗朗索瓦·法布对环路的观察非常好,但我们可以更进一步。代码正在执行大约8000个写操作,大小不变,内容几乎相同。我们可以在一次操作中准备一个缓冲区。你知道吗

# Prepare buffer with static portions
addresses = list(range(1,4096)) + list(range(8193,12288))
dataoffset = 2+5+1+2
linelength = dataoffset+8+1
buf = bytearray(b"".join(b'0x%05x\t0x%08x\n'%(j,0)
                        for j in addresses))

# Later on, fill in data
for line,address in enumerate(addresses):
    offset = linelength*line+dataoffset
    buf[offset:offset+8] = b"%08x"%memory[address]
f.write(buf)

这意味着系统调用要少得多。很可能我们可以更进一步,例如,将内存作为缓冲区读取,并使用b2a_hex或类似的格式,而不是每个单词的字符串格式。也可以预先计算偏移量,而不是使用枚举。你知道吗

你的循环效率很低。当值不在范围内时,实际上是在徒劳地迭代。你花了很多时间测试指数。你知道吗

不要做一个循环和两个测试。只需创建两个没有索引测试的循环(请注意,如果我们尊重您的测试,则会跳过第一个索引:

for j in range(1,4096):
    f.write('0x%05x\t0x%08x\n' %(j, memory[j]))
for j in range(8193,12288):
    f.write('0x%05x\t0x%08x\n' %(j, memory[j]))

可能更具pythonic和更简洁(不使用memory[j],因此有机会更快):

import itertools
for start,end in ((1,4096),(8193,12288)):
    sl = itertools.islice(memory,start,end)
    for j,m in enumerate(sl,start):
        f.write('0x%05x\t0x%08x\n' %(j, m))

外部循环保存了2个循环(因此如果有更多偏移,只需将它们添加到元组列表中)。islice对象创建了一个内存片,但没有复制。它每次迭代时不检查数组是否越界,因此可以更快。它还没有被定格,但是写入磁盘可能也要花费很多时间。你知道吗

相关问题 更多 >