hel*_*ker 13 python performance file-io
我知道有一些关于文件读取,二进制数据处理和使用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']))])
Run Code Online (Sandbox Code Playgroud)
有了这段代码,我得到每兆字节读取2.2秒,带有2Mb RAM的双核,而我的文件通常有20+ Mb,这会产生一些非常恼人的延迟(特别考虑到另一个基准共享软件程序我试图镜像加载文件快点吧.
我想知道的是:
谢谢阅读
(我已经发布了一些关于我的这个职位的问题,我希望它们在概念上都是无关的,我也希望不要过于重复.)
编辑: 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
Run Code Online (Sandbox Code Playgroud)
与一次读取文件或以任何形式使用文件相比,速度提升非常令人印象深刻struct
.
jfs*_*jfs 15
您可以array
用来读取您的数据:
import array
import os
fn = 'data.bin'
a = array.array('h')
a.fromfile(open(fn, 'rb'), os.path.getsize(fn) // a.itemsize)
Run Code Online (Sandbox Code Playgroud)
它比快40个倍struct.unpack
从@ samplebias的答案.
如果文件只有20-30M,为什么不读取整个文件,在一次调用中解码nums unpack
,然后通过遍历数组在你的通道中分配它们:
data = open('data.bin', 'rb').read()
values = struct.unpack('%dh' % len(data)/2, data)
del data
# iterate over channels, and assign from values using indices/slices
Run Code Online (Sandbox Code Playgroud)
快速测试显示,这导致struct.unpack('h', f.read(2))
20M文件的速度提高了10倍.