Bruke Python Timeit for å time koden din

I denne opplæringen lærer du hvordan du bruker timeit-funksjonen fra Pythons timeit-modul. Du lærer hvordan du kan time enkle uttrykk og funksjoner i Python.

Timing av koden din kan hjelpe deg med å få et estimat over utførelsestiden for et kodestykke og også identifisere delene av koden som må optimaliseres.

Vi starter med å lære syntaksen til Pythons timeit-funksjon. Og så skal vi kode eksempler for å forstå hvordan du bruker det til å tidsblokkere kode og funksjoner i Python-modulen. La oss begynne.

Slik bruker du Python timeit-funksjonen

Timeit-modulen er en del av Python-standardbiblioteket, og du kan importere den:

import timeit

Syntaksen for å bruke timeit-funksjonen fra timeit-modulen er som vist nedenfor:

timeit.timeit(stmt, setup, number)

Her:

  • stmt er kodebiten hvis utførelsestid skal måles. Du kan spesifisere den som en enkel Python-streng eller en flerlinjestreng, eller sende inn navnet på den anropbare.
  • Som navnet antyder, angir oppsett kodebiten som bare må kjøres én gang, ofte som en forutsetning for at stmt skal kjøre. Anta for eksempel at du beregner utførelsestiden for å lage en NumPy-matrise. I dette tilfellet er import av numpy oppsettskoden og selve opprettelsen er setningen som skal tidsbestemmes.
  • Parameternummeret angir antall ganger stmt kjøres. Standardverdien for tall er 1 million (1000000), men du kan også sette denne parameteren til en hvilken som helst annen verdi du ønsker.

Nå som vi har lært syntaksen for å bruke timeit()-funksjonen, la oss begynne å kode noen eksempler.

Timing av enkle Python-uttrykk

I denne delen skal vi prøve å måle utførelsestiden til enkle Python-uttrykk ved å bruke timeit.

Start en Python REPL og kjør følgende kodeeksempler. Her beregner vi utførelsestiden for eksponentierings- og etasjedelingsoperasjoner for 10 000 og 100 000 kjøringer.

  Hvor mye er Google Cloud Latency (GCP) mellom regioner?

Legg merke til at vi sender inn setningen for å bli tidsbestemt som en Python-streng og bruker semikolon for å skille de forskjellige uttrykkene i setningen.

>>> import timeit
>>> timeit.timeit('3**4;3//4',number=10000)
0.0004020999999738706

>>> timeit.timeit('3**4;3//4',number=100000)
0.0013780000000451764

Kjører Python timeit på kommandolinjen

Du kan også bruke timeit på kommandolinjen. Her er kommandolinjeekvivalenten til timeit-funksjonskallet:

$ python-m timeit -n [number] -s [setup] [stmt]
  • python -m timeit representerer at vi kjører timeit som hovedmodul.
  • n er et kommandolinjealternativ som angir antall ganger koden skal kjøres. Dette tilsvarer tallargumentet i timeit()-funksjonskallet.
  • Du kan bruke alternativet -s for å definere oppsettkoden.

Her omskriver vi forrige eksempel ved å bruke kommandolinjeekvivalenten:

$ python -m timeit -n 100000 '3**4;3//4'
100000 loops, best of 5: 35.8 nsec per loop

I dette eksemplet beregner vi utførelsestiden for den innebygde len()-funksjonen. Initialiseringen av strengen er oppsettkoden som sendes inn ved å bruke s-alternativet.

$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)'
100000 loops, best of 5: 239 nsec per loop

Legg merke til at vi får utførelsestiden for best av 5 løp i utgangen. Hva betyr dette? Når du kjører timeit på kommandolinjen, er gjentakelsesalternativet r satt til standardverdien 5. Dette betyr at kjøringen av stmt for det angitte antall ganger gjentas fem ganger, og den beste av kjøringstidene returneres.

Analyse av strengreverseringsmetoder ved hjelp av timeit

Når du arbeider med Python-strenger, vil du kanskje reversere dem. De to vanligste tilnærmingene til strengreversering er som følger:

  • Ved å bruke strengskjæring
  • Bruke reversed()-funksjonen og join()-metoden

Omvendt Python-strenger ved bruk av strengskjæring

La oss gå over hvordan strengskjæring fungerer, og hvordan du kan bruke den til å snu en Python-streng. Bruker syntaksen noen-streng[start:stop] returnerer en del av strengen som starter ved indeksstart og strekker seg opp til indeksstopp-1. La oss ta et eksempel.

Tenk på følgende streng «Python». Strengen har lengde 6 og listen over indekser er 0, 1, 2 opp til 5.

>>> string_1 = 'Python'

Når du spesifiserer både start- og stoppverdiene, får du en strengskive som strekker seg fra start til stopp-1. Derfor, string_1[1:4] returnerer «yth».

  Hvordan konvertere valuta i Microsoft Excel

>>> string_1 = 'Python'
>>> string_1[1:4]
'yth'

Når du ikke spesifiserer startverdien, brukes standard startverdi på null, og skiven starter ved indeks null og strekker seg opp til stopp – 1.

Her er stoppverdien 3, så skiven starter på indeks 0 og går opp til indeks 2.

>>> string_1[:3]
'Pyt'

Når du ikke inkluderer stoppindeksen, ser du at skiven starter fra startindeksen (1) og strekker seg opp til slutten av strengen.

>>> string_1[1:]
'ython'

Hvis du ignorerer både start- og stoppverdiene, returneres en del av hele strengen.

>>> string_1[::]
'Python'

La oss lage en skive med trinnverdien. Sett start-, stopp- og trinnverdiene til henholdsvis 1, 5 og 2. Vi får en del av strengen som starter på 1 og strekker seg opp til 4 (unntatt sluttpunktet 5) som inneholder hvert andre tegn.

>>> string_1[1:5:2]
'yh'

Når du bruker et negativt trinn, kan du få en skive som starter på slutten av strengen. Med trinnet satt til -2, streng_1[5:2:-2] gir følgende skive:

>>> string_1[5:2:-2]
'nh'

Så for å få en reversert kopi av strengen, hopper vi over start- og stoppverdiene og setter trinnet til -1, som vist:

>>> string_1[::-1]
'nohtyP'

Oppsummert: streng[::-1] returnerer en omvendt kopi av strengen.

Reversere strenger ved hjelp av innebygde funksjoner og strengmetoder

Den innebygde reversed()-funksjonen i Python vil returnere en omvendt iterator over elementene i strengen.

>>> string_1 = 'Python'
>>> reversed(string_1)
<reversed object at 0x00BEAF70>

Så du kan gå gjennom den omvendte iteratoren ved å bruke en for-løkke:

for char in reversed(string_1):
    print(char)

Og få tilgang til elementene i strengen i motsatt rekkefølge.

# Output
n
o
h
t
y
P

Deretter kan du kalle join()-metoden på den omvendte iteratoren med syntaksen: .join(reversed(some-string)).

Kodebiten nedenfor viser et par eksempler hvor skilletegnet er henholdsvis en bindestrek og et mellomrom.

>>> '-'.join(reversed(string1))
'n-o-h-t-y-P'
>>> ' '.join(reversed(string1))
'n o h t y P'

Her ønsker vi ingen skilletegn; så sett skillelinjen til en tom streng for å få en omvendt kopi av strengen:

>>> ''.join(reversed(string1))
'nohtyP'

Å bruke ”.join(reversed(some-string)) returnerer en reversert kopi av strengen.

  Hvordan bli en OSCP [Full Guide]

Sammenligne utførelsestider ved å bruke timeit

Så langt har vi lært to tilnærminger for å reversere Python-strenger. Men hvem av dem er raskest? La oss finne det ut.

I et tidligere eksempel der vi tidsbestemte enkle Python-uttrykk, hadde vi ingen oppsettkode. Her snur vi Python-strengen. Mens strengreverseringsoperasjonen kjøres i det antall ganger som er spesifisert med nummer, er oppsettkoden initialiseringen av strengen som bare kjøres én gang.

>>> import timeit
>>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000)
0.04951830000001678
>>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000)
0.12858760000000302

For samme antall kjøringer for å reversere den gitte strengen, er strengslicing-tilnærmingen raskere enn å bruke join()-metoden og reversed()-funksjonen.

Timing Python-funksjoner Bruke timeit

I denne delen, la oss lære hvordan du kan time Python-funksjoner med timeit-funksjonen. Gitt en liste over strenger, returnerer følgende funksjon hasDigit listen over strenger som har minst ett siffer.

def hasDigit(somelist):
     str_with_digit = []
     for string in somelist:
         check_char = [char.isdigit() for char in string]
         if any(check_char):
            str_with_digit.append(string)
     return str_with_digit

Nå ønsker vi å måle utførelsestiden til denne Python-funksjonen hasDigit() ved å bruke timeit.

La oss først identifisere setningen som skal tidsbestemmes (stmt). Det er kallet til funksjonen hasDigit() med en liste over strenger som argument. La oss deretter definere oppsettkoden. Kan du gjette hva oppsettkoden skal være?

For at funksjonskallet skal kjøre vellykket, må oppsettkoden inneholde følgende:

  • Definisjonen av funksjonen hasDigit()
  • Initialiseringen av argumentlisten over strenger

La oss definere oppsettkoden i oppsettstrengen, som vist nedenfor:

setup = """
def hasDigit(somelist):
    str_with_digit = []
    for string in somelist:
      check_char = [char.isdigit() for char in string]
      if any(check_char):
        str_with_digit.append(string)
    return str_with_digit
thislist=['puffin3','7frost','blue']
     """

Deretter kan vi bruke timeit-funksjonen og få utførelsestiden til hasDigit()-funksjonen for 100 000 kjøringer.

import timeit
timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output
0.2810094920000097

Konklusjon

Du har lært hvordan du bruker Pythons timeit-funksjon til å tidsstyre uttrykk, funksjoner og andre callables. Dette kan hjelpe deg med å benchmarke koden din, sammenligne utførelsestidene til forskjellige implementeringer av samme funksjon og mer.

La oss se gjennom hva vi har lært i denne opplæringen. Du kan bruke timeit()-funksjonen med syntaksen timeit.timeit(stmt=…,setup=…,number=…). Alternativt kan du kjøre timeit på kommandolinjen for å time korte kodebiter.

Som et neste trinn kan du utforske hvordan du bruker andre Python-profileringspakker som line-profiler og memprofiler for å profilere koden din for henholdsvis tid og minne.

Deretter lærer du hvordan du beregner tidsforskjell i Python.