64 lines
1.5 KiB
Python
64 lines
1.5 KiB
Python
#!/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()
|