Ho il seguente metodo Python piccolo che è di gran lunga le prestazioni hotspot (secondo il mio profiler,> 95% del tempo di esecuzione è trascorso qui) in un programma molto più grande:Come velocizzare questo codice Python?
def topScore(self, seq):
ret = -1e9999
logProbs = self.logProbs # save indirection
l = len(logProbs)
for i in xrange(len(seq) - l + 1):
score = 0.0
for j in xrange(l):
score += logProbs[j][seq[j + i]]
ret = max(ret, score)
return ret
Il codice viene eseguito nell'implementazione Jython di Python, non in CPython, se questo è importante. seq
è una stringa di sequenza del DNA, nell'ordine di 1.000 elementi. logProbs
è un elenco di dizionari, uno per ogni posizione. L'obiettivo è trovare il punteggio massimo di qualsiasi lunghezza l
(nell'ordine di 10-20 elementi) sottosuccessione di seq
.
Mi rendo conto che tutto questo ciclo è inefficiente a causa di un sovraccarico di interpretazione e sarebbe molto più veloce in un linguaggio compilato staticamente/JIT. Tuttavia, non sono disposto a cambiare lingua. Innanzitutto, ho bisogno di un linguaggio JVM per le librerie che sto usando, e questo tipo di vincoli alle mie scelte. In secondo luogo, non voglio tradurre questo codice all'ingrosso in una lingua JVM di livello inferiore. Tuttavia, sono disposto a riscrivere questo hotspot in qualcos'altro, se necessario, anche se non ho idea di come interfacciarlo o quale sarebbe l'overhead.
In aggiunta alla lentezza a thread singolo di questo metodo, non riesco neanche a far sì che il programma scaletri molte 4 CPU in termini di parallelizzazione. Dato che trascorre quasi tutto il suo tempo nell'hotspot a 10 linee che ho pubblicato, non riesco a capire quale potrebbe essere il collo di bottiglia.
Non riesco a capire la struttura dati che stai utilizzando. Potresti pubblicare un esempio ridotto di 'seq' e' logProbs'? – katrielalex
Il mio primo pensiero è stato numpy, quindi forse qualcosa su questa pagina potrebbe essere utile: http://stackoverflow.com/questions/316410/is-there-a-good-numpy-clone-for-jython –
Il mio secondo pensiero è annullando l'iterazione in modo tale da passare al seq una sola volta, ma ciò probabilmente significa che logProbs e score diventano più complessi e potrebbero non ridurre il lavoro svolto. –