Created
September 18, 2025 13:02
-
-
Save 1st1/f03e816f34a61e4d46c78ff98baf4818 to your computer and use it in GitHub Desktop.
uuid bench
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This benchmark is AI-generated | |
| """ | |
| Benchmark script comparing pure Python UUID implementation | |
| with C implementation. | |
| Tests: | |
| - uuid4() generation | |
| - uuid7() generation | |
| - UUID instantiation from string | |
| - UUID instantiation from bytes | |
| - str(uuid) conversion | |
| """ | |
| import time | |
| import uuid | |
| import statistics | |
| import sys | |
| from typing import Callable, List, Tuple | |
| # Access both implementations | |
| try: | |
| # Try to get the implementation classes directly | |
| py_UUID = uuid._py_UUID | |
| c_UUID = uuid._c_UUID | |
| print("Successfully loaded both Python and C UUID implementations") | |
| print(f" Python UUID: {py_UUID}") | |
| print(f" C UUID: {c_UUID}") | |
| except AttributeError as e: | |
| print(f"Error accessing UUID implementations: {e}") | |
| print("Make sure you're using a version with the C extension compiled") | |
| sys.exit(1) | |
| def benchmark_batch(func: Callable, batch_size: int = 1000, iterations: int = 100) -> Tuple[float, float, float]: | |
| """ | |
| Run a benchmark on a function in batches for better timing accuracy. | |
| Returns: (mean_time, median_time, std_dev) in microseconds per operation | |
| """ | |
| # Warmup | |
| for _ in range(10): | |
| for _ in range(100): | |
| func() | |
| # Actual benchmark | |
| times = [] | |
| for _ in range(iterations): | |
| start = time.perf_counter() | |
| for _ in range(batch_size): | |
| func() | |
| end = time.perf_counter() | |
| time_per_op = ((end - start) * 1_000_000) / batch_size | |
| times.append(time_per_op) | |
| return ( | |
| statistics.mean(times), | |
| statistics.median(times), | |
| statistics.stdev(times) if len(times) > 1 else 0, | |
| ) | |
| def format_result(name: str, py_result: Tuple[float, float, float], c_result: Tuple[float, float, float]) -> str: | |
| """Format benchmark results for display.""" | |
| py_mean, py_median, py_std = py_result | |
| c_mean, c_median, c_std = c_result | |
| speedup = py_mean / c_mean if c_mean > 0 else 0 | |
| result = f"\n{name}:\n" | |
| result += f" Python: mean={py_mean:.3f}us, median={py_median:.3f}us, std={py_std:.3f}us\n" | |
| result += f" C: mean={c_mean:.3f}us, median={c_median:.3f}us, std={c_std:.3f}us\n" | |
| result += f" Speedup: {speedup:.2f}x faster" | |
| return result | |
| def print_separator(char: str = "=", width: int = 60): | |
| """Print a simple separator line.""" | |
| print(char * width) | |
| def main(): | |
| print("\nUUID Implementation Benchmark") | |
| print("Comparing Pure Python vs C Extension") | |
| print_separator() | |
| # Test data for instantiation tests | |
| test_uuid_str = "550e8400-e29b-41d4-a716-446655440000" | |
| test_uuid_bytes = b"\x55\x0e\x84\x00\xe2\x9b\x41\xd4\xa7\x16\x44\x66\x55\x44\x00\x00" | |
| # Create test UUIDs for str() conversion and pickling | |
| py_test_uuid = py_UUID(test_uuid_str) | |
| c_test_uuid = c_UUID(test_uuid_str) | |
| results = [] | |
| # ========== UUID4 Generation ========== | |
| print("\n1. UUID4 Generation") | |
| print_separator("-", 40) | |
| print("Benchmarking uuid4() generation...") | |
| py_uuid4_func = uuid._py_uuid4 | |
| c_uuid4_func = uuid._c_uuid4 | |
| py_uuid4_result = benchmark_batch(py_uuid4_func, batch_size=1000, iterations=100) | |
| c_uuid4_result = benchmark_batch(c_uuid4_func, batch_size=1000, iterations=100) | |
| result_str = format_result("uuid4() generation", py_uuid4_result, c_uuid4_result) | |
| print(result_str) | |
| results.append(("uuid4() generation", py_uuid4_result, c_uuid4_result)) | |
| # ========== UUID7 Generation ========== | |
| print("\n2. UUID7 Generation") | |
| print_separator("-", 40) | |
| print("Benchmarking uuid7() generation...") | |
| py_uuid7_func = uuid._py_uuid7 | |
| c_uuid7_func = uuid._c_uuid7 | |
| py_uuid7_result = benchmark_batch(py_uuid7_func, batch_size=1000, iterations=100) | |
| c_uuid7_result = benchmark_batch(c_uuid7_func, batch_size=1000, iterations=100) | |
| result_str = format_result("uuid7() generation", py_uuid7_result, c_uuid7_result) | |
| print(result_str) | |
| results.append(("uuid7() generation", py_uuid7_result, c_uuid7_result)) | |
| # ========== UUID from String ========== | |
| print("\n3. UUID Instantiation from String") | |
| print_separator("-", 40) | |
| print(f"Benchmarking UUID('{test_uuid_str}')...") | |
| py_from_str_result = benchmark_batch( | |
| lambda: py_UUID(test_uuid_str), batch_size=1000, iterations=100 | |
| ) | |
| c_from_str_result = benchmark_batch( | |
| lambda: c_UUID(test_uuid_str), batch_size=1000, iterations=100 | |
| ) | |
| result_str = format_result("UUID from string", py_from_str_result, c_from_str_result) | |
| print(result_str) | |
| results.append(("UUID from string", py_from_str_result, c_from_str_result)) | |
| # ========== UUID from Bytes ========== | |
| print("\n4. UUID Instantiation from Bytes") | |
| print_separator("-", 40) | |
| print("Benchmarking UUID(bytes=...)...") | |
| py_from_bytes_result = benchmark_batch( | |
| lambda: py_UUID(bytes=test_uuid_bytes), batch_size=1000, iterations=100 | |
| ) | |
| c_from_bytes_result = benchmark_batch( | |
| lambda: c_UUID(bytes=test_uuid_bytes), batch_size=1000, iterations=100 | |
| ) | |
| result_str = format_result("UUID from bytes", py_from_bytes_result, c_from_bytes_result) | |
| print(result_str) | |
| results.append(("UUID from bytes", py_from_bytes_result, c_from_bytes_result)) | |
| # ========== str(UUID) Conversion ========== | |
| print("\n5. str(UUID) Conversion") | |
| print_separator("-", 40) | |
| print("Benchmarking str(uuid) conversion...") | |
| py_str_result = benchmark_batch( | |
| lambda: str(py_test_uuid), batch_size=1000, iterations=100 | |
| ) | |
| c_str_result = benchmark_batch( | |
| lambda: str(c_test_uuid), batch_size=1000, iterations=100 | |
| ) | |
| result_str = format_result("str(uuid) conversion", py_str_result, c_str_result) | |
| print(result_str) | |
| results.append(("str(uuid) conversion", py_str_result, c_str_result)) | |
| # ========== Summary ========== | |
| print_separator() | |
| print("\nSUMMARY") | |
| print_separator() | |
| print("\nPerformance Comparison (C vs Python):") | |
| print("-" * 50) | |
| print(f"{'Operation':<25} {'Speedup':>10} {'C Mean (us)':>15}") | |
| print("-" * 50) | |
| for name, py_result, c_result in results: | |
| speedup = py_result[0] / c_result[0] if c_result[0] > 0 else 0 | |
| print(f"{name:<25} {speedup:>9.2f}x {c_result[0]:>14.3f}") | |
| print("-" * 50) | |
| # Calculate overall average speedup | |
| speedups = [] | |
| for _, py_result, c_result in results: | |
| if c_result[0] > 0: | |
| speedups.append(py_result[0] / c_result[0]) | |
| if speedups: | |
| avg_speedup = statistics.mean(speedups) | |
| print(f"\nOverall Average Speedup: {avg_speedup:.2f}x") | |
| # ========== Detailed Performance Table ========== | |
| print_separator() | |
| print("\nDETAILED PERFORMANCE DATA") | |
| print_separator() | |
| print("\nAll times in microseconds (us) per operation:") | |
| print("-" * 80) | |
| print(f"{'Operation':<25} {'Implementation':<15} {'Mean':>10} {'Median':>10} {'Std Dev':>10}") | |
| print("-" * 80) | |
| for name, py_result, c_result in results: | |
| print(f"{name:<25} {'Python':<15} {py_result[0]:>10.3f} {py_result[1]:>10.3f} {py_result[2]:>10.3f}") | |
| print(f"{'':<25} {'C':<15} {c_result[0]:>10.3f} {c_result[1]:>10.3f} {c_result[2]:>10.3f}") | |
| print() | |
| print("=" * 80) | |
| print("\nBenchmark completed successfully!") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment