我知道以前有一些关于文件读取、二进制数据处理和使用struct进行整数转换的问题,所以我来这里询问一段代码,我认为这段代码运行时间太长了。正在读取的文件是一个多通道数据样本记录(短整数),其中包含数据间隔(因此是嵌套的for语句)。代码如下:

# channel_content is a dictionary, channel_content[channel]['nsamples'] is a string
for rec in xrange(number_of_intervals)):
for channel in channel_names:
channel_content[channel]['recording'].extend(
[struct.unpack( "h", f.read(2))[0]
for iteration in xrange(int(channel_content[channel]['nsamples']))])

有了这段代码,我每兆字节读取2.2秒,双核内存为2 Mb,我的文件通常有20+Mb,这会带来一些非常烦人的延迟(特别是考虑到另一个基准共享软件程序,我正试图以更快的速度镜像加载文件)。

我想知道的是:如果有一些违反“良好实践”的情况:排列不好的循环、重复操作所需时间超过必要时间、使用效率低下的容器类型(字典?)等等

如果这个读取速度是正常的,或者对于Python是正常的,并且如果读取速度

如果创建C++编译扩展可能会提高性能,如果它是推荐的方法。

(当然)如果有人建议对此代码进行一些修改,最好是基于以前类似操作的经验。

谢谢你的阅读

(我已经发布了一些关于我这项工作的问题,我希望它们在概念上都不相关,我也希望不要太重复。)

Edit:channel_names是一个列表,因此我做了@eumiro建议的更正(删除键入的括号)

编辑:我现在同意塞巴斯蒂安的建议,将array与fromfile()方法一起使用,并很快将最终代码放在这里。此外,每一个贡献对我都非常有用,我非常高兴地感谢每一个善意的回答。

使用array.fromfile()一次,然后通过切片大数组为每个通道交替扩展一个数组后的最终形式:

fullsamples = array('h')
fullsamples.fromfile(f, os.path.getsize(f.filename)/fullsamples.itemsize - f.tell())
position = 0
for rec in xrange(int(self.header['nrecs'])):
for channel in self.channel_labels:
samples = int(self.channel_content[channel]['nsamples'])
self.channel_content[channel]['recording'].extend(
fullsamples[position:position+samples])
position += samples

每次读取一点文件,或者以任何形式使用struct,速度的提高都令人印象深刻。