Skip to content
3 changes: 3 additions & 0 deletions python-performance-optimization-guide/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Python Performance Optimization: A Practical Guide

This folder provides the code examples for the Real Python tutorial Python Performance Optimization: A Practical Guide.
25 changes: 25 additions & 0 deletions python-performance-optimization-guide/step-1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import timeit


def calculate_order_total(items):
total = 0
for item in items:
total = total + item["price"] * item["quantity"]
return total


order = [
{"price": 19.99, "quantity": 3},
{"price": 5.50, "quantity": 10},
{"price": 42.00, "quantity": 1},
] * 100

runs = 500_000

print(f"{calculate_order_total(order):.2f}")

order_time = timeit.timeit(
lambda: calculate_order_total(order), number=runs
)
print(f"total for {runs:,} runs: {order_time:.4f} seconds")
print(f"per call: {order_time / runs * 1_000_000:.1f} microseconds")
11 changes: 11 additions & 0 deletions python-performance-optimization-guide/step-2-fast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import timeit

numbers_list = list(range(100_000))
target = 99_999

numbers_set = set(numbers_list)

set_time = timeit.timeit(lambda: target in numbers_set, number=1000)

print(target in numbers_set)
print(f"set membership: {set_time:.8f} seconds")
10 changes: 10 additions & 0 deletions python-performance-optimization-guide/step-2-slow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import timeit

numbers_list = list(range(100_000))

target = 99_999

list_time = timeit.timeit(lambda: target in numbers_list, number=1000)

print(target in numbers_list)
print(f"list membership: {list_time:.8f} seconds")
14 changes: 14 additions & 0 deletions python-performance-optimization-guide/step-3-fast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from collections import Counter
import timeit

words = ["apple", "pear", "apple", "cherry", "pear", "apple"] * 1000


def counter_count(items):
return Counter(items)


print(counter_count(words))

counter_time = timeit.timeit(lambda: counter_count(words), number=1000)
print(f"collections.Counter: {counter_time:.4f} seconds")
19 changes: 19 additions & 0 deletions python-performance-optimization-guide/step-3-slow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import timeit

words = ["apple", "pear", "apple", "cherry", "pear", "apple"] * 1000


def manual_count(items):
counts = {}
for item in items:
if item in counts:
counts[item] += 1
else:
counts[item] = 1
return counts


print(manual_count(words))

manual_time = timeit.timeit(lambda: manual_count(words), number=1000)
print(f"manual loop: {manual_time:.4f} seconds")
19 changes: 19 additions & 0 deletions python-performance-optimization-guide/step-4-fast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from functools import cache
import timeit

numbers = list(range(2_000_000))
target = 1_999_999


@cache
def find_index_cached(target):
for i, value in enumerate(numbers):
if value == target:
return i
return -1


print(find_index_cached(target))

fast_time = timeit.timeit(lambda: find_index_cached(target), number=20)
print(f"with cache: {fast_time:.8f} seconds")
18 changes: 18 additions & 0 deletions python-performance-optimization-guide/step-4-slow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import timeit

numbers = list(range(2_000_000))


def find_index(target):
for i, value in enumerate(numbers):
if value == target:
return i
return -1


target = 1_999_999

print(find_index(target))

slow_time = timeit.timeit(lambda: find_index(target), number=20)
print(f"without cache: {slow_time:.4f} seconds")
Loading