我有一些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]))
答案 0 :(得分:2)
你的循环非常低效。当值不在范围内时,您实际上无需迭代。而且你花了很多时间测试指数。
不要做一个循环&amp; 2次测试。只需在没有索引测试的情况下创建2个循环(请注意,如果我们尊重您的测试,则会跳过第一个索引:
dref = FirebaseDatabase.getInstance().getReference("clusters/Community");
dref.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String name = dataSnapshot.child("name").getValue(String.class);
int messagesSentCount = dataSnapshot.child("messagesSentCount").getValue(Integer.class);
list.add(name);
adapter.notifyItemInserted(list.size()-1);
}
也许更多pythonic&amp;更简洁(并且不使用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]))
因此它有机会更快):
memory[j]
外部循环保存2个循环(因此,如果有更多的偏移,只需将它们添加到元组列表中)。 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))
对象创建内存片但不创建副本。它迭代而不会每次检查数组超出范围的索引,因此可以更快。它尚未成功,但写入磁盘可能也需要花费大量时间。
答案 1 :(得分:1)
Jean-FrançoisFabre对循环的观察非常好,但我们可以更进一步。该代码执行大约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
或类似内容而不是每个单词的字符串格式。预先计算偏移量而不是使用枚举量也可能有意义。