Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Mäta Funktionsprestanda | Förståelse och Mätning av Prestanda
Optimeringstekniker i Python

bookMäta Funktionsprestanda

Även om mätning av strängbaserade kodsnuttar ibland kan vara tillräckligt, saknar detta tillvägagångssätt flexibilitet. Att använda timeit med funktioner ger ett mer effektivt sätt att mäta prestanda, och dekoratorer förenklar processen att mäta prestanda för flera funktioner på ett rent och modulärt sätt.

Använda timeit med funktioner

timeit kan mäta prestandan hos funktioner direkt genom att skicka in ett callable (dvs. en funktion) istället för en sträng. Detta är mer flexibelt och lättläst än att använda strängar, särskilt när du vill benchmarka komplexa funktioner.

1234567891011121314
import timeit import numpy as np # Function to test def generate_squares(): return np.array([x ** 2 for x in range(1000000)]) # Measure time using a callable (function) iterations = 15 execution_time = timeit.timeit(generate_squares, number=iterations) # Calculate average time per run average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Vi skickar generate_squares som funktionen (callable) som ska tidmätas med timeit.timeit(). Precis som tidigare anger parametern number hur många gånger funktionen ska köras (15 gånger). Genomsnittlig exekveringstid beräknas sedan genom att dividera den totala tiden med antalet körningar.

Denna metod är renare och mer effektiv för att benchmarka riktiga funktioner, och den undviker overheaden av att utvärdera kod från en sträng.

123456789
import timeit import numpy as np code_snippet = 'np.array([x ** 2 for x in range(1000000)])' iterations = 15 execution_time = timeit.timeit(code_snippet, number=iterations) average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Hoppsan, vi fick följande fel: NameError: name 'np' is not defined. Felet uppstår eftersom timeit.timeit() kör koden isolerat, så den har inte tillgång till numpy om du inte uttryckligen importerar det i argumentet setup:

# Import numpy in timeit's environment
setup = 'import numpy as np'  
execution_time = timeit.timeit(code_snippet, setup=setup, number=iterations)

Att använda funktioner är renare, minskar fel och kräver inte hantering av externa importer via en setup-sträng.

Förbättrad prestandamätning med dekoratorer

Att tillämpa samma tidsmätningslogik på flera funktioner är en vanlig praxis, och en dekorator erbjuder ett rent och effektivt sätt att implementera detta utan att upprepa kod.

Varje gång en funktion anropas, körs den som vanligt, men med sömlös prestandamätning tillagd. Dekoratorer ger flera fördelar: de ökar återanvändbarheten genom att tillämpa samma logik på flera funktioner, förbättrar tydligheten genom att separera tidsmätningslogik från kärnfunktionalitet och möjliggör anpassning, såsom att justera antalet iterationer eller lägga till ytterligare mätvärden för prestandaanalys.

123456789101112131415161718192021
import timeit # Decorator to time the execution of a function def timeit_decorator(number=1): def decorator(func): def wrapper(*args, **kwargs): # Measure time with timeit total_time = timeit.timeit(lambda: func(*args, **kwargs), number=number) average_time = total_time / number print(f'{func.__name__} executed in {average_time:.6f} seconds (average over {number} runs)') return func(*args, **kwargs) return wrapper return decorator # Function to measure @timeit_decorator(number=30) def generate_squares(): return [x**2 for x in range(1000000)] # Calling the decorated function squares_array = generate_squares()
copy

Nu kommer varje gång du anropar en funktion som är dekorerad med @timeit_decorator att dess prestanda automatiskt mätas och resultaten visas.

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 1. Kapitel 3

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Awesome!

Completion rate improved to 7.69

bookMäta Funktionsprestanda

Svep för att visa menyn

Även om mätning av strängbaserade kodsnuttar ibland kan vara tillräckligt, saknar detta tillvägagångssätt flexibilitet. Att använda timeit med funktioner ger ett mer effektivt sätt att mäta prestanda, och dekoratorer förenklar processen att mäta prestanda för flera funktioner på ett rent och modulärt sätt.

Använda timeit med funktioner

timeit kan mäta prestandan hos funktioner direkt genom att skicka in ett callable (dvs. en funktion) istället för en sträng. Detta är mer flexibelt och lättläst än att använda strängar, särskilt när du vill benchmarka komplexa funktioner.

1234567891011121314
import timeit import numpy as np # Function to test def generate_squares(): return np.array([x ** 2 for x in range(1000000)]) # Measure time using a callable (function) iterations = 15 execution_time = timeit.timeit(generate_squares, number=iterations) # Calculate average time per run average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Vi skickar generate_squares som funktionen (callable) som ska tidmätas med timeit.timeit(). Precis som tidigare anger parametern number hur många gånger funktionen ska köras (15 gånger). Genomsnittlig exekveringstid beräknas sedan genom att dividera den totala tiden med antalet körningar.

Denna metod är renare och mer effektiv för att benchmarka riktiga funktioner, och den undviker overheaden av att utvärdera kod från en sträng.

123456789
import timeit import numpy as np code_snippet = 'np.array([x ** 2 for x in range(1000000)])' iterations = 15 execution_time = timeit.timeit(code_snippet, number=iterations) average_time = execution_time / iterations print(f'Average execution time: {average_time:.6f} seconds')
copy

Hoppsan, vi fick följande fel: NameError: name 'np' is not defined. Felet uppstår eftersom timeit.timeit() kör koden isolerat, så den har inte tillgång till numpy om du inte uttryckligen importerar det i argumentet setup:

# Import numpy in timeit's environment
setup = 'import numpy as np'  
execution_time = timeit.timeit(code_snippet, setup=setup, number=iterations)

Att använda funktioner är renare, minskar fel och kräver inte hantering av externa importer via en setup-sträng.

Förbättrad prestandamätning med dekoratorer

Att tillämpa samma tidsmätningslogik på flera funktioner är en vanlig praxis, och en dekorator erbjuder ett rent och effektivt sätt att implementera detta utan att upprepa kod.

Varje gång en funktion anropas, körs den som vanligt, men med sömlös prestandamätning tillagd. Dekoratorer ger flera fördelar: de ökar återanvändbarheten genom att tillämpa samma logik på flera funktioner, förbättrar tydligheten genom att separera tidsmätningslogik från kärnfunktionalitet och möjliggör anpassning, såsom att justera antalet iterationer eller lägga till ytterligare mätvärden för prestandaanalys.

123456789101112131415161718192021
import timeit # Decorator to time the execution of a function def timeit_decorator(number=1): def decorator(func): def wrapper(*args, **kwargs): # Measure time with timeit total_time = timeit.timeit(lambda: func(*args, **kwargs), number=number) average_time = total_time / number print(f'{func.__name__} executed in {average_time:.6f} seconds (average over {number} runs)') return func(*args, **kwargs) return wrapper return decorator # Function to measure @timeit_decorator(number=30) def generate_squares(): return [x**2 for x in range(1000000)] # Calling the decorated function squares_array = generate_squares()
copy

Nu kommer varje gång du anropar en funktion som är dekorerad med @timeit_decorator att dess prestanda automatiskt mätas och resultaten visas.

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 1. Kapitel 3
some-alt