Python 获取头数据的子进程头与DictReader(获取文件头信息的最快方法)
我对从文件中提取列标题数据以供以后使用的最快方法感兴趣。下面我尝试了两种不同的方法:Subprocess/head和DictReader。结果是多个不同的量级Python 获取头数据的子进程头与DictReader(获取文件头信息的最快方法),python,csv,subprocess,Python,Csv,Subprocess,我对从文件中提取列标题数据以供以后使用的最快方法感兴趣。下面我尝试了两种不同的方法:Subprocess/head和DictReader。结果是多个不同的量级 import subprocess from csv import DictReader def head_test(): pipe = subprocess.Popen(['head','-n','1','file_data.txt'],stdout=subprocess.PIPE, universal_newlines=Tr
import subprocess
from csv import DictReader
def head_test():
pipe = subprocess.Popen(['head','-n','1','file_data.txt'],stdout=subprocess.PIPE, universal_newlines=True)
for row in pipe.stdout:
fields = row.strip().split('\t')
def dictreader_test():
with open('file_data.txt') as f:
f_info = DictReader(f,delimiter='\t')
fields = f_info.fieldnames
def fopen_test():
with open('file_data.txt') as f:
fields = next(f).strip().split('\t')
def rstrip_test():
with open('file_data.txt') as f:
fields = next(f).rstrip().split('\t')
if __name__ == '__main__':
import timeit
print(timeit.timeit('head_test()', setup='from __main__ import head_test', number=10000))
print(timeit.timeit('dictreader_test()', setup='from __main__ import dictreader_test', number=100000))
print(timeit.timeit('fopen_test()', setup='from __main__ import fopen_test', number=100000))
print(timeit.timeit('rstrip_test()', setup='from __main__ import rstrip_test', number=100000))
结果:
34.6136500835
0.195073127747
最后3次测试的附加结果达到100k:
1.85791897774
0.983640909195
0.973639011383
即使在head_测试中注释掉整个for循环,它也只占大约20%的时间
两个问题:
-有没有更快捷的方法来获取列标题数据?
-这两种方法之间的主要性能差异是什么原因
更新:在响应建议子流程的附加测试中添加。Popen实际上启动了一个外部程序。在Unices上,这意味着分叉进程并用另一个可执行文件覆盖子进程。这比仅仅读取一个文件的开销要大得多
DictReader
只需读取文件的第一行,而head
除了创建进程外,还必须读取文件的第一行。子进程。Popen
实际上启动了一个外部程序。在Unices上,这意味着分叉进程并用另一个可执行文件覆盖子进程。这比仅仅读取一个文件的开销要大得多
DictReader
只需读取文件的第一行,而head
除了创建进程外,还必须读取文件的第一行。以下操作应比DictReader
稍快一些:
fields = next(open('file_data.txt')).strip().split('\t')
这是因为文件对象(由open()
返回)是从文件中产生行的可编辑对象,因此next(open('file_data.txt'))
将返回文件的第一行
DictReader
和Popen
在性能上的主要区别在于调用单独的程序来读取文件并通过管道将结果传递给Python程序所需的开销。
fields = next(open('file_data.txt')).strip().split('\t')
这是因为文件对象(由open()
返回)是从文件中产生行的可编辑对象,因此next(open('file_data.txt'))
将返回文件的第一行
DictReader
和Popen
在性能上的主要区别在于调用单独的程序来读取文件并通过管道将结果传递给Python程序所需的开销。forks经过了优化,但如果它太过读取文件,为什么不使用Python?我不确定你想说什么?所以你不这么认为它对OP测量的差异负责?我刚刚评论了fork/copy parent/rewrite child部分,但是你是对的,在一个单独的过程中重编文件确实很慢。fork是经过优化的,但是如果它太过读取文件,为什么不使用python呢?我不确定你想说什么?所以你不认为这是OP测量的差异造成的?我只是对fork/copy parent/rewrite child部分发表了评论,然而,您是对的,在单独的过程中重编文件确实很慢。您可能希望使用open('file_data.txt')作为f:fields=next(f).strip().split('\t')
或使用open('csv.txt','rb')作为f:names=f.readline().rstrip().split('\t')
(能够将f
传递到csv.reader()
)将在一分钟内发布更新后的性能信息。之后我不需要使用file对象,因此readline()格式是不必要的,尽管rstrip()在每100k次迭代中会中断.01秒。您可能希望打开('file_data.txt')时使用f:fields=next(f).strip().split('\t')
或打开('csv.txt','rb'))由于f:names=f.readline().rstrip().split('\t')
(为了能够将f
传递到csv.reader()
)将在一分钟内发布更新的性能信息。之后我不需要再发送文件对象,因此不需要使用readline()格式,尽管rstrip()每100k次迭代就减少0.01秒通常不值得创建一个新流程,除非您要做大量的工作。尤其是在窗户上;Unix通常更好,Linux尤其如此……但即使在Linux上,也要比在Python解释器中进行几个函数调用花费更长的时间。另一方面,如果您只做了少量的工作,那么性能成本可能并不重要。浪费掉的3.4毫秒真的会有所不同吗?通常不值得创建一个新流程,除非你要做大量的工作。尤其是在窗户上;Unix通常更好,Linux尤其如此……但即使在Linux上,也要比在Python解释器中进行几个函数调用花费更长的时间。另一方面,如果您只做了少量的工作,那么性能成本可能并不重要。浪费掉的3.4毫秒真的会有所不同吗?