【发布时间】:2011-08-13 19:51:13
【问题描述】:
我知道之前有一些关于使用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']))])
使用此代码,我使用具有 2Mb RAM 的双核读取每兆字节 2.2 秒,而我的文件通常有 20+ Mb,这会产生一些非常烦人的延迟(特别是考虑到我试图镜像的另一个基准共享软件程序加载文件的速度更快)。
我想知道的:
- 如果有一些违反“良好做法”的行为:循环安排不当、重复操作花费的时间超过必要时间、使用效率低下的容器类型(字典?)等。
- 如果这个读取速度正常,或者Python正常,如果读取速度正常
- 如果创建 C++ 编译扩展可能会提高性能,以及是否是推荐的方法。
- (当然)如果有人建议对此代码进行一些修改,最好基于以前的类似操作经验。
感谢阅读
(我已经发了几个关于我这个工作的问题,希望它们都是概念上无关的,也希望不要太重复。)
编辑: channel_names 是一个列表,所以我做了@eumiro 建议的更正(删除拼写错误的括号)
编辑:我目前正在接受 Sebastian 的建议,即使用 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相比,速度提升非常令人印象深刻。
【问题讨论】:
-
你确定
for channel in [channel_names]:?这将使用channel = channel_names运行一个循环。另外,您从哪里获得channel_content[channel]中的所有值? -
您是否尝试分析您的代码?
-
@eumiro:你是对的,不应该有括号,因为 channel_names 实际上是一个字符串列表(名称本身)。
-
@9000: 我对很多
print "starting this"和print "ending this"进行了一些“业余”分析,但我承认我不确定如何正确分析,更不用说该怎么做根据分析结果提高性能。 -
你的意思是
(os.path.getsize(f.filename) - f.tell()) / fullsamples.itemsize?
标签: python performance file-io