2015-04-10 2 views
0

У меня есть следующий код, который считывает несколько файлов и помещает некоторую информацию или каждую строку в базу данных MySQL. Однако этот процесс идет медленно.Чтение в параллельных многократных файлах в Python

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 

Как я могу прочитать несколько файлов одновременно, чтобы ускорить мою программу?

+0

Вы пробовали модуль «многопроцессорности»? – Wolph

+0

Замедление может быть связано с фиксацией базы данных после каждой строки. Если вы можете совершать только один раз в 1000 строк, это может улучшить скорость. – styts

+0

Как бы это сделать, @styts – user2979409

ответ

0

Вы выполняете вызов базы данных, поэтому я могу предположить, что ваше приложение связано с I/O. В вашем сценарии вы можете использовать модуль threading. Сделайте каждую нить сделать это IO вызывает что-то вроде этого:

Prep файлы:

[email protected]:/tmp/test$ for i in {a,b,c,d,e}; do echo foo_$i > $i;done 
[email protected]:/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() 

Выход 1-й раз:

a => foo_a 

e => foo_e 

b => foo_b 

c => foo_c 

d => foo_d 

Выход 2-го раза:

d => foo_d 

e => foo_e 

a => foo_a 

b => foo_b 

c => foo_c 
0

Прежде всего вы можете посмотреть, какие строки являются медленными, есть хороший line_profiler для python, который вы можете проверить. Тогда, может быть, вы можете подумать о том, чтобы разделить функцию на две части: одну для чтения файлов параллельно, а другую - на всю всю информацию в БД.

Приветствия

0

одно предложение, предполагая, что каждый файл не очень большой file.Just поставил

db1.commit() 

вне for loop. Это означает, что он должен выполнить, когда заканчивается for loop.

Затем, если вы хотите прочитать файл parallely, вы можете использовать Threads, Multiprocessing.

Смежные вопросы