在Python中并行读取多个文件

时间:2015-04-10 12:31:18

标签: python mysql multithreading parsing

我有以下代码,它读取多个文件并将一些信息或每行放入MySQL数据库。但是,这个过程很慢。

def extractAF(files_vcf):
...
for infile_name in sorted(files_vcf):
    print infile_name
    ###single files
    vcf_reader = vcf.Reader(open(infile_name, 'r'))
    for record in vcf_reader:
        snp_position='_'.join([record.CHROM, str(record.POS)])
        ref_F = float(record.INFO['DP4'][0])
        ref_R = float(record.INFO['DP4'][1])
        alt_F = float(record.INFO['DP4'][2])
        alt_R = float(record.INFO['DP4'][3])
        AF = (alt_F+alt_R)/(alt_F+alt_R+ref_F+ref_R)
        if not snp_position in snp_dict:
            sql_insert_table = "INSERT INTO snps VALUES ('" + snp_position + "'," + ",".join(list(('0') for _ in range(len(files_vcf)))) + ")"
            cursor = db1.cursor()
            cursor.execute(sql_insert_table)
            db1.commit()
            snp_dict.append(snp_position)
        sql_update = "UPDATE snps SET " + str(z) + "g=" + str(AF) + " WHERE snp_pos='" + snp_position + "'";
        cursor = db1.cursor()
        cursor.execute(sql_update)
        db1.commit()
    z+=1
return snp_dict

如何同时阅读多个文件以加快我的程序?

3 个答案:

答案 0 :(得分:0)

首先你可以看一下哪些行是慢行,你可以查看一个很好的line_profiler for python。 然后,也许您可​​以考虑将功能拆分为两个,一个用于并行读取文件,另一个用于将所有信息压缩到DB中。

干杯

答案 1 :(得分:0)

一个建议,假设每个文件都不是一个非常大的文件。只需要

db1.commit()

for loop之外。这意味着它必须在for loop完成时执行。

然后,如果您想阅读文件parallely,可以使用ThreadsMultiprocessing

答案 2 :(得分:0)

您正在进行数据库调用,因此我可以假设您的应用程序受I / O限制。在您的方案中,您可以使用threading模块。让每个线程都进行IO调用,如下所示:

准备文件:

root@123-PC:/tmp/test$ for i in {a,b,c,d,e}; do echo foo_$i > $i;done
root@123-PC:/tmp/test$ ls
a  b  c  d  e

并行运行代码:

import threading
import time
import random

def worker(f_n):
    with open(f_n) as f:
        time.sleep(random.random())
        print f_n, " => ", f.read()

f_list = ['a','b', 'c', 'd', 'e']

threads = []
for f_n in f_list:
    t = threading.Thread(target=worker, args=(f_n))
    threads.append(t)

for t in threads:
    t.start()


for t in threads:
    t.join()

输出第一时间:

a  =>  foo_a

e  =>  foo_e

b  =>  foo_b

c  =>  foo_c

d  =>  foo_d

输出第二次:

d  =>  foo_d

e  =>  foo_e

a  =>  foo_a

b  =>  foo_b

c  =>  foo_c