Jestem całkiem nowy w Pythonie i napisałem (prawdopodobnie bardzo brzydki) skrypt, który ma losowo wybierać podzbiór sekwencji z pliku fastq. Plik fastq przechowuje informacje w blokach po cztery wiersze. Pierwszy wiersz w każdym bloku zaczyna się od znaku "@". Plik fastq, którego używam jako pliku wejściowego, ma rozmiar 36 GB i zawiera około 14 000 000 linii.Jak mogę przyspieszyć mój skrypt Pythona?
Próbowałem przerobić istniejący skrypt, który wykorzystał zbyt dużo pamięci i udało mi się bardzo zmniejszyć zużycie pamięci. Ale skrypt trwa wiecznie i nie rozumiem dlaczego.
parser = argparse.ArgumentParser()
parser.add_argument("infile", type = str, help = "The name of the fastq input file.", default = sys.stdin)
parser.add_argument("outputfile", type = str, help = "Name of the output file.")
parser.add_argument("-n", help="Number of sequences to sample", default=1)
args = parser.parse_args()
def sample():
linesamples = []
infile = open(args.infile, 'r')
outputfile = open(args.outputfile, 'w')
# count the number of fastq "chunks" in the input file:
seqs = subprocess.check_output(["grep", "-c", "@", str(args.infile)])
# randomly select n fastq "chunks":
seqsamples = random.sample(xrange(0,int(seqs)), int(args.n))
# make a list of the lines that are to be fetched from the fastq file:
for i in seqsamples:
linesamples.append(int(4*i+0))
linesamples.append(int(4*i+1))
linesamples.append(int(4*i+2))
linesamples.append(int(4*i+3))
# fetch lines from input file and write them to output file.
for i, line in enumerate(infile):
if i in linesamples:
outputfile.write(line)
grep-krok trwa praktycznie w ogóle czasu, ale po ponad 500 minut, skrypt wciąż nie zaczął pisać do pliku wyjściowego. Więc przypuszczam, że jest to jeden z kroków pomiędzy grep a ostatnią pętlą for, która trwa tak długo. Ale nie rozumiem, który krok dokładnie i co mogę zrobić, aby przyspieszyć.
Powinieneś rozważyć [profilowanie] (https://docs.python.org/2/library/profile.html) swojego programu, aby zobaczyć, które kroki się zawiesią.Czy próbowałeś też uruchomić swój kod na mniejszym pliku i sprawdzić, czy działa on do końca? Kolejnym krokiem, który rozważam później w optymalizacji, jest wykorzystanie wątków i procesów wieloprocesorowych do podziału pracy. –
Nie wywoływać 'int' przez cały czas w pętli. Użyj również instrukcji 'with'. – Veedrac