Zoeken…


Opmerkingen

Wanneer u probeert de prestaties van een Python-script te verbeteren, moet u eerst en vooral de bottleneck van uw script kunnen vinden en opmerken dat geen enkele optimalisatie een slechte keuze in gegevensstructuren of een fout in uw algoritmeontwerp kan compenseren. Het identificeren van knelpunten in de prestaties kan worden gedaan door uw script te profileren . Ten tweede, probeer niet te vroeg in uw coderingsproces te optimaliseren ten koste van leesbaarheid / ontwerp / kwaliteit. Donald Knuth heeft de volgende verklaring afgelegd over optimalisatie:

“We moeten kleine efficiënties vergeten, zeg ongeveer 97% van de tijd: voortijdige optimalisatie is de wortel van alle kwaad. Toch moeten we onze kansen in die kritische 3% niet laten liggen. ”

Code profilering

Eerst en vooral moet u in staat zijn om het knelpunt van uw script te vinden en op te merken dat geen enkele optimalisatie een slechte keuze in gegevensstructuur of een fout in uw algoritmeontwerp kan compenseren. Ten tweede, probeer niet te vroeg in uw coderingsproces te optimaliseren ten koste van leesbaarheid / ontwerp / kwaliteit. Donald Knuth heeft de volgende verklaring afgelegd over optimalisatie:

"We moeten kleine efficiënties vergeten, zeggen ongeveer 97% van de tijd: voortijdige optimalisatie is de wortel van alle kwaad. Toch moeten we onze kansen in die kritische 3% niet laten liggen"

Om je code te profileren heb je verschillende tools: cProfile (of het langzamere profile ) uit de standaardbibliotheek, line_profiler en timeit . Elk van hen heeft een ander doel.

cProfile is een determistische profiler: functieaanroep, functieterugkomst en uitzonderingsgebeurtenissen worden bewaakt en er worden nauwkeurige timings gemaakt voor de intervallen tussen deze gebeurtenissen (tot 0,001 sec). De bibliotheekdocumentatie ([ https://docs.python.org/2/library/profile.html cialis cialis1]) biedt ons een eenvoudig gebruik

import cProfile
def f(x):
    return "42!"
cProfile.run('f(12)')

Of als u liever delen van uw bestaande code inpakt:

import cProfile, pstats, StringIO
pr = cProfile.Profile()
pr.enable()
# ... do something ...
# ... long ...
pr.disable()
sortby = 'cumulative'
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print s.getvalue()

Hiermee maakt u uitvoer die eruitziet als de onderstaande tabel, waar u snel kunt zien waar uw programma het grootste deel van zijn tijd doorbrengt en welke functies u kunt optimaliseren.

         3 function calls in 0.000 seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.000    0.000    0.000    0.000 <stdin>:1(f)
     1    0.000    0.000    0.000    0.000 <string>:1(<module>)
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

De module line_profiler ([ https://github.com/rkern/line_profiler. line_profiler ]) is handig om een regel voor regel analyse van uw code te hebben. Dit is duidelijk niet beheersbaar voor lange scripts, maar is gericht op fragmenten. Raadpleeg de documentatie voor meer informatie. De eenvoudigste manier om te beginnen is om het kernprof-script te gebruiken zoals uitgelegd op de pakketpagina, houd er rekening mee dat u handmatig de functie (s) moet opgeven om te profileren.

$ kernprof -l script_to_profile.py

kernprof maakt een instantie van LineProfiler en voegt deze in de naamruimte __builtins__ in met het __builtins__ . Het is geschreven om te worden gebruikt als decorateur, dus in je script decoreer je de functies die je wilt profileren met @profile .

@profile
def slow_function(a, b, c):
    ...

Het standaardgedrag van kernprof is om de resultaten in een binair bestand script_to_profile.py.lprof . U kunt kernprof vertellen om de opgemaakte resultaten direct op de terminal te bekijken met de optie [-v / - view]. Anders kunt u de resultaten later als volgt bekijken:

$ python -m line_profiler script_to_profile.py.lprof

Eindelijk biedt timeit een eenvoudige manier om één liners of kleine uitdrukking te testen, zowel vanaf de opdrachtregel als vanuit de python-shell. Deze module beantwoordt vragen als, is het sneller om een lijst te begrijpen of de ingebouwde list() bij het transformeren van een set in een lijst. Zoek naar het setup trefwoord of -s optie om setup code toe te voegen.

>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.8187260627746582

van een terminal

$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 40.3 usec per loop


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow