#!/usr/bin/env python3 """ Scenario 1: The Optimized Version ================================= This version calls the C implementation via ctypes. SETUP: gcc -O2 -fPIC -shared -o libprime.so prime.c EXERCISES: 1. Compare: time python3 prime_fast.py 2. Profile: py-spy record -o prime_fast.svg -- python3 prime_fast.py 3. Compare the flamegraphs - what changed? """ import ctypes import sys import os # Load the shared library script_dir = os.path.dirname(os.path.abspath(__file__)) lib_path = os.path.join(script_dir, "libprime.so") try: libprime = ctypes.CDLL(lib_path) except OSError as e: print(f"Error: Could not load {lib_path}") print("Please compile first: gcc -O2 -fPIC -shared -o libprime.so prime.c") sys.exit(1) # Define function signatures libprime.is_prime.argtypes = [ctypes.c_int64] libprime.is_prime.restype = ctypes.c_int libprime.count_primes.argtypes = [ctypes.c_int64] libprime.count_primes.restype = ctypes.c_int64 def is_prime(n): """Python wrapper for C is_prime.""" return bool(libprime.is_prime(n)) def count_primes(limit): """Count all primes up to limit.""" count = 0 for n in range(2, limit + 1): if is_prime(n): count += 1 return count def main(): limit = 1_000_000 if len(sys.argv) > 1: limit = int(sys.argv[1]) print(f"Counting primes up to {limit} (using C library)...") result = count_primes(limit) print(f"Found {result} primes") if __name__ == "__main__": main()