Ich ist die Umsetzung einen Algorithmus in PythonBiopython verwenden. Ich habe mehrere Ausrichtungen (Sätze von Sequenzen gleicher Länge) in FASTA Dateien gespeichert. Jede Ausrichtung enthält zwischen 500 und 30000 Seq. Und jede Sequenz ist etwa 17000 Elemente lang. Jede Sequenz wird als Bio.SeqRecord.SeqRecord Objekt gespeichert (überprüfen Sie die SeqRecord object's API documentation für weitere Informationen), die nicht nur die Sequenz, sondern auch einige Informationen darüber enthält. Ich las es von der Festplatte mit Bio.AlignIO.read() (überprüfen Sie die AlignIO module's API documentation für weitere Informationen), die gibt ein MultipleSeqAlignment Objekt:Des Versuch, einen Python-Algorithmus parallelisieren Multithreading verwenden und die Vermeidung von GIL Einschränkungen
seqs = AlignIO.read(seqs_filename, 'fasta')
len_seqs = seqs.get_alignment_length()
stats = {'-': [0.0] * len_seqs, 'A': [0.0] * len_seqs,
'G': [0.0] * len_seqs, 'C': [0.0] * len_seqs,
'T': [0.0] * len_seqs}
Ich schließe diese Skizze aus Gründen der Übersichtlichkeit:
Weil ich mag paralelize die Analyse der Ausrichtung, ich Zuordnung zu jedem verfügbaren CPU ein Fragment davon mit der threading module (mehr Details über, warum ich diese Entscheidung später getroffen habe):
Die Statistikvariable ist eine gemeinsame Variable, in der ich einige Informationen über die Analyse speichere (wie Sie im ersten Codeausschnitt sehen können). Da jede CPU verschiedene Positionen dieser geteilten Variablen ändern wird, denke ich, dass es keine Notwendigkeit der Zugriffssteuerung noch irgendein Synchronisationsgrundelement gibt. Der Hauptgrund, warum ich Threads anstelle von Prozessen verwende, ist, weil Ich möchte vermeiden, das ganze MultipleSeqAlignment Objekt für jede CPU zu kopieren. Ich habe etwas Forschung getan und some stackoverflow posts darüber gefunden.
Ich habe auch einige Informationen über die „gefürchtete“ Python Globaler Interpreter Lock (GIL) lesen (I große Info gefunden sowohl bei stackoverflow und programmers bei Stapelaustausch) aber Ich bin immer noch nicht zu 100% sicher, ob mein Algorithmus ist davon betroffen. Soweit ich weiß, lade ich nacheinander Sequenzen in den Speicher und mache so IO bei jeder Iteration. Deshalb denke ich, dass es eine gute Idee ist, Threads zu verwenden, wie in this stackoverflow post erwähnt wurde, die ich bereits erwähnt habe. Die Grundstruktur der Analyse sieht etwa so aus (die jeder Thread ausgeführt wird):
for seq in seqs:
num_column = start_column
for column in seq.seq[start_column:end_column].upper():
# [...]
try:
stats[elem][num_column] = get_some_info(column)
except TypeError:
raise TypeError(('"stats" argument should be a '
'dict of lists of int'))
ich einige Performance-Tests durchgeführt haben die timeit module und the time command unter Verwendung der Argumente -f „% e% M“ können Sie nicht überprüfen nur die verstrichene Echtzeit (in Sekunden), aber auch die maximale Resident-Set-Größe des Prozesses während seiner Lebensdauer (in KB). Es scheint, dass die Ausführungszeit mit Threads die Ausführungszeit der sequenziellen Implementierung geteilt durch die Anzahl der Threads ist. Für die maximale Resident-Set-Größe kann ich immer noch kein Muster finden.
Wenn Sie irgendwelche anderen Vorschläge über Leistung oder Klarheit haben, würde ich sie sehr schätzen.
Vielen Dank im Voraus.
Soweit Ihr Ruf in Betracht gezogen wurde, war das Beste, was ich tun konnte, war Ihre Frage zu verbessern, jetzt haben Sie 10+ Ruf ich denke, aber sorry kann ich Ihnen nicht helfen mit Frage – ZdaR
Dank @Annol_uppal! Ich habe gerade die Frage bearbeitet :-) –