2013-12-05 3 views
1

Я запускаю поиск и редактирование программы. Сейчас у меня есть файл с уникальным идентификатором в первом столбце и данными в 10-м и 11-м столбцах, которые необходимо исправить. Этот файл имеет около 40-100M строк. Файл с правильной информацией имеет в 4 раза больше строк и находится в формате, где он повторяется каждые 4 строки, причем строка 1n имеет идентификатор, строка 2 имеет правильные данные для столбца 10, а строка 4 имеет правильные данные для столбца 11. У меня есть две программы, одна из которых разбивает файл 1 на 250000 фрагментов строки и параллельно запускает следующую программу на нескольких ядрах.Как ускорить свою программу

#! /bin/bash 
#$ -l h_rt=01:00:00,vf=1G 
#$ -pe smp 1 
#$ -cwd 
#$ -j y 
#$ -N unmasked 
#$ -V 

for line in `cut -f 1 $1`; do 
     seq=`awk -v a="$line" '$1~a{getline;print;exit}' ../406.fastq` 
     qual=`awk -v a="$line" '$1~a{getline;getline;getline;print;exit}' ../406.fastq` 
     awk -v s="$seq" -v q="$qual" -v l="$line" 'FS="\t" {if ($1~l) {$10=s;$11=q; print $0}}' $1 >> $1\D 
done 
rm $1 

Unfortunetly эта программа занимает около 4-6 секунд, чтобы запустить цикл, и в 250000 строк, которые будут принимать около 5 дней и занимают большую часть компьютерного кластера я использую.

Любые советы по выполнению этого быстрее и эффективнее? Я открыт для всего, что угодно ...

+2

Вы можете начать с того, что не запускаете 'awk' над одним и тем же файлом дважды, чтобы вытащить разные значения. Это просто расточительно. –

+0

Посмотрите на [Gnu parallel] (http://www.gnu.org/software/parallel/). – Yohann

+0

Это не проблема с ЦП. Параллелизм не поможет, если вы не собираетесь распространять данные по нескольким дискам. – slim

ответ

1

Shell scripting не очень подходит для такого рода работы. Эта программа порождает три недолговечных awk-процесса на строку ввода, а пока процесс создания UNIX дешевле, чем в Windows, вы все равно не хотите оплачивать накладные расходы процесса 300M раз!

(Исправление: создание процесса является наименее забот Это чтение через файл 400M линии дважды на каждой итерации.!)

Используйте свой предпочтительный «реальный» язык сценариев - я был бы соблазн использовать Perl, но Python - прекрасный выбор. Возможно, это можно сделать и в автономном скрипте awk, но если бы вы были так хороши в awk, вы бы не задавали этот вопрос - и Perl существует, поэтому вам не нужно быть awk-гуру!

Напишите сценарий вдоль линий этого псевдокода, который держит оба файла открытым и предполагает, что обе они имеют информацию в том же порядке.

open file1 and file2 
read 1 line from file1 and 4 lines from file2 into string variables 
while(reads didn't fail) { 
    parse desired information from lines 
    output in the format you want 
    read 1 line from file1 and 4 lines from file2 into string variables 
} 
close both files 

Возможно, вы обнаружите, что это достаточно быстро, что нет необходимости пытаться его параллелизировать. Я ожидаю, что это будет ограничено доступом к диску, а не ЦП.


Если эти два файла находятся не в одном порядке, у вас будет больше проблем. Сортировка элементов 100M не из дешевых. Самый простой способ - сначала перебрать более длинный файл, введя нужные вам значения в структуру данных карты, такую ​​как хеш-память Perl или словарь Python, или даже такую ​​базу данных, как Redis, и затем перебирайте более короткий файл, вытягивая значения, которые вы необходимо переписать строки из карты.

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