2016-03-18 8 views
1

Ich führe ein Stück Code mit Python2.7 und der cProfile sagt 35s während cProfile auf Pypy sagt 73s! Wie ist das möglich unter der Annahme, Pypy ist schneller Dolmetscher. Der Code implementiert die BWT-Transformation bei der Eingabe eines Bitstroms. Ich habe zwei Dateien: bwt.py, die in fm.py aufgerufen wird. Ich rief die Funktion als:Wie ist es möglich, Python schneller als Pypy

pypy -m cProfle fm.py inputfile 

und dann

python -m cProfle fm.py inputfile 

Der Code von bwt.py folgende ist:

def rotations(t): 
    ''' Return list of rotations of input string t ''' 
    tt = t * 2 
    return [ tt[i:i+len(t)] for i in xrange(0, len(t)) ] 

def bwm(t): 
    return sorted(rotations(t)) 

def bwtViaBwm(t): 
    ''' Given T, returns BWT(T) by way of the BWM ''' 
    return ''.join(map(lambda x: x[-1], bwm(t))) 

def rankBwt(bw): 
    ''' Given BWT string bw, return parallel list of B-ranks. Also 
     returns tots: map from character to # times it appears. ''' 
    tots = dict() 
    ranks = [] 
    for c in bw: 
     if c not in tots: tots[c] = 0 
     ranks.append(tots[c]) 
     tots[c] += 1 
    return ranks, tots 
def firstCol(tots): 
    ''' Return map from character to the range of rows prefixed by 
     the character. ''' 
    first = {} 
    totc = 0 
    for c, count in sorted(tots.iteritems()): 
     first[c] = (totc, totc + count) 
     totc += count 
    return first 

def reverseBwt(bw): 
    ''' Make T from BWT(T) ''' 
    ranks, tots = rankBwt(bw) 
    first = firstCol(tots) 
    rowi = 0 # start in first row 
    t = '$' # start with rightmost character 
    while bw[rowi] != '$': 
     c = bw[rowi] 
     t = c + t # prepend to answer 
     # jump to row that starts with c of same rank 
     rowi = first[c][0] + ranks[rowi] 
    return t 



def suffixArray(s): 
    satups = sorted([(s[i:], i) for i in xrange(0, len(s))]) 
    print satups 
    return map(lambda x: x[1], satups) 

def bwtViaSa(t): 
    # Given T, returns BWT(T) by way of the suffix array 
    bw = [] 
    for si in suffixArray(t): 
     if si == 0: 
      bw.append('$') 
     else: 
      bw.append(t[si-1]) 
    return ''.join(bw) # return string-ized version of list bw 



def readfile(sd): 
    s="" 
    with open(sd,'r') as myfile: 
     s =myfile.read() 
    return s.rstrip('\n') 
def writefile(sd,N): 
    with open(sd, "wb") as sink: 
     sink.write(''.join(random.choice(string.ascii_uppercase + string.digits) for _ in xrange(N))) 
     sink.write('$') 
    return 



def main(): 
    data=readfile('inp') 
    b=bwtViaBwm(data) 
    ranks,tots = rankBwt(b) 
    print "Input stream = "+ data 
    print "BWT = " + bwtViaSa(data) 
    print '\n'.join(bwm(data)) 
    print ("Lc ranking:") 
    print zip(b,ranks) 

    fc=[x[0] for x in bwm(data)] 
    fc= ''.join(fc) 
    print ("First column="+ fc) 
    ranks,tots = rankBwt(fc) 
    print("Fc ranking:") 
    print zip(fc,ranks) 

    print reverseBwt(bwtViaSa(data)) 

if __name__=='__main__': 
    main() 

Und das ist die Codeform die fm.py der ich nenne es durch pypy:

import bwt 
import sys 
from collections import Counter 

def build_FM(fname): 
    stream=bwt.readfile(fname) 
    #print bwt.suffixArray(stream) 
    b=bwt.bwtViaBwm(stream) 
    ranks,tots = bwt.rankBwt(b) 
    lc=zip(b,ranks) 
    fc=[x[0] for x in bwt.bwm(stream)] 
    fc= ''.join(fc) 
    fc= zip(fc,ranks) 
    #print lc,fc 


def main(): 
    fname= sys.argv[1] 
    build_FM(fname) 
    return 


if __name__=='__main__': 
    main() 
+0

bitte ein Beispiel posten – kilojoules

+1

Wenn es länger dauert, mit Pypy zu laufen, dann scheint es, dass Ihre Annahme falsch ist .... für diesen bestimmten Code und Daten. –

+0

@WilliamPursell Nun, ich dachte, Pypy ist immer schneller. Ich liege falsch. Ich muss suchen, welche Art von Code pypy outperforms – curious

Antwort

2

Pypy nicht garantieren eine schnellere Ausführung eines Programms.

Erstens, die Optimierungen, die es implementiert, benötigen Zeit (manchmal eine erhebliche Menge an Zeit) zu laufen. Zweitens wird nicht jeder Code schneller unter Pypy laufen, obwohl die meisten es tun. Die relative Geschwindigkeit des profilierten Codes kann sich zwischen ihnen sehr unterscheiden - der Pypy-Code ist ein Low-Level und daher ist die Einführung von Profiling wahrscheinlich (relativ gesehen) mehr als CPython zu bremsen. Was sind die Ergebnisse ohne Profiling aktiv?

Wir müssten Ihr Programm sehen, um viel mehr Informationen dazu zu liefern.

+0

Ich habe meine Frage mit Code bearbeitet – curious

-1

Ihr Skript weist eine wahnsinnige Speichermenge in rotations() zu (O (N ** 2) wobei N die Größe der Eingabedatei ist). Wie in cProfile und vmprof zu sehen ist, wird die meiste Zeit dort verbracht.

Was Sie sehen, ist daher Unterschiede in der Speicherbehandlung zwischen PyPy und CPython. Meine Vermutung ist, dass Sie tauschen und dass PyPy einen höheren Spitzenspeicherverbrauch hat.

Verwandte Themen