diff --git a/python-performance-optimization-guide/README.md b/python-performance-optimization-guide/README.md new file mode 100644 index 0000000000..d780ecf82e --- /dev/null +++ b/python-performance-optimization-guide/README.md @@ -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. \ No newline at end of file diff --git a/python-performance-optimization-guide/step-1.py b/python-performance-optimization-guide/step-1.py new file mode 100644 index 0000000000..4d85eb0c4c --- /dev/null +++ b/python-performance-optimization-guide/step-1.py @@ -0,0 +1,20 @@ +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 + +print(calculate_order_total(order)) + +order_time = timeit.timeit( + lambda: calculate_order_total(order), number=500_000 +) +print(f"calculate_order_total: {order_time:.4f} seconds") \ No newline at end of file diff --git a/python-performance-optimization-guide/step-2-fast.py b/python-performance-optimization-guide/step-2-fast.py new file mode 100644 index 0000000000..8a8d9ba410 --- /dev/null +++ b/python-performance-optimization-guide/step-2-fast.py @@ -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") \ No newline at end of file diff --git a/python-performance-optimization-guide/step-2-slow.py b/python-performance-optimization-guide/step-2-slow.py new file mode 100644 index 0000000000..50d8fcc9b9 --- /dev/null +++ b/python-performance-optimization-guide/step-2-slow.py @@ -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") \ No newline at end of file diff --git a/python-performance-optimization-guide/step-3-fast.py b/python-performance-optimization-guide/step-3-fast.py new file mode 100644 index 0000000000..ca5a730918 --- /dev/null +++ b/python-performance-optimization-guide/step-3-fast.py @@ -0,0 +1,15 @@ +import timeit + +words = ["apple", "pear", "apple", "cherry", "pear", "apple"] * 1000 + +from collections import Counter + +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") \ No newline at end of file diff --git a/python-performance-optimization-guide/step-3-slow.py b/python-performance-optimization-guide/step-3-slow.py new file mode 100644 index 0000000000..e4afb63ca2 --- /dev/null +++ b/python-performance-optimization-guide/step-3-slow.py @@ -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") \ No newline at end of file diff --git a/python-performance-optimization-guide/step-4-fast.py b/python-performance-optimization-guide/step-4-fast.py new file mode 100644 index 0000000000..e231c106cf --- /dev/null +++ b/python-performance-optimization-guide/step-4-fast.py @@ -0,0 +1,20 @@ +import timeit + +numbers = list(range(2_000_000)) +target = 1_999_999 + +from functools import cache + +@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") \ No newline at end of file diff --git a/python-performance-optimization-guide/step-4-slow.py b/python-performance-optimization-guide/step-4-slow.py new file mode 100644 index 0000000000..91fcd7d114 --- /dev/null +++ b/python-performance-optimization-guide/step-4-slow.py @@ -0,0 +1,16 @@ +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") \ No newline at end of file