Skip to main content

Explain why Python code is slow, not just where

Project description

pyperf-why

Explain why Python code is slow, not just where.

pyperf-why is a Rust-powered Python diagnostic tool that identifies performance anti-patterns in your code and explains what Python is doing internally that makes it slow.

Unlike traditional profilers that tell you where time is spent, pyperf-why tells you why it's slow and suggests concrete fixes.

Installation

pip install pyperf-why

Quick Start

from pyperf_why import explain

@explain
def process_data():
    result = []
    for i in range(1000):
        result.append(i * 2)  # Dynamic list growth
    return result

Output:

Found 1 performance issue in 'process_data':
  • 1 high severity

🔴 Issue #1: dynamic_list_growth
   Location: line 5

   Why it's slow:
   Python reallocates list memory on each append() call (~1000 times).
   Each reallocation copies the entire list to a new memory location.
   This creates O(n²) memory operations.

   How to fix:
   Use list comprehension: [expr for i in range(n)]
   or pre-allocate: result = [None] * n, then assign values.

What It Detects (v0.1)

  1. Dynamic List Growth - list.append() in loops causing repeated reallocations
  2. Nested Loops - O(n²) or worse complexity patterns
  3. Function Calls in Loops - Overhead from repeated function invocation

Features

  • Rust-powered analysis - Fast pattern detection
  • Zero dependencies - Just install and use
  • Human-readable output - Clear explanations, not cryptic metrics
  • Actionable suggestions - Concrete fixes, not vague advice

Usage

As a decorator

@explain
def my_function():
    # your code here
    pass

Direct call

def my_function():
    # your code here
    pass

report = explain(my_function)

Skip execution

@explain(run=False)  # Don't execute, just analyze structure
def my_function():
    pass

How It Works

  1. Python extracts - AST, bytecode, and runtime patterns
  2. Rust analyzes - Pattern matching and heuristic evaluation
  3. Report generated - Human-readable explanations with fixes

Philosophy

Profilers tell you where. pyperf-why tells you why.

This is a teaching tool as much as a diagnostic tool. It helps developers understand Python's performance characteristics.

Non-Goals

  • Not a profiler replacement (use cProfile for hotspot analysis)
  • Not a benchmark tool (use timeit for precise timing)
  • Not an automatic optimizer (suggestions require manual implementation)

Development

# Clone the repo
git clone https://github.com/jagadhis/pyperf-why
cd pyperf-why

# Install Rust (if needed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install maturin
pip install maturin

# Build and install
maturin develop

# Run tests
cargo test  # Rust tests
pytest tests/  # Python tests

Roadmap

v0.1 (Current)

  • ✅ List growth detection
  • ✅ Nested loops detection
  • ✅ Function calls in loops

v0.2 (Planned)

  • Generator vs list comprehension
  • Dict/set operations
  • String concatenation patterns
  • Global variable access
  • Import statements in loops

v0.3 (Future)

  • Interactive mode
  • CI/CD integration
  • VSCode extension

Contributing

Contributions welcome! Please read CONTRIBUTING.md first.

License

MIT

Credits

Built with:

  • PyO3 - Rust ↔ Python bindings
  • maturin - Build and publish Rust-based Python packages

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyperf_why-0.1.0.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyperf_why-0.1.0-cp313-cp313-macosx_11_0_arm64.whl (227.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

File details

Details for the file pyperf_why-0.1.0.tar.gz.

File metadata

  • Download URL: pyperf_why-0.1.0.tar.gz
  • Upload date:
  • Size: 18.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.10.2

File hashes

Hashes for pyperf_why-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8458067f892a4281cc8d716bb5df6355cad724f80a10a91132113fbbe42a7108
MD5 895315e20633fa00558ff4f030c21a88
BLAKE2b-256 56cbecb6459dea2d030344e1f71cc4470552af028c11b2a6d46de7af594d7b49

See more details on using hashes here.

File details

Details for the file pyperf_why-0.1.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyperf_why-0.1.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b1837a06900fa70df8607db3971aa9c042ece8af0f9cf18e499539833cceb0f7
MD5 4dcfa015c29a0de049db7c889af37976
BLAKE2b-256 923c493d24d5651f7e447804d2f64de0b911782b0cf3108bceffa988d1f6ee21

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page