Skip to main content

Graph-theoretic structural optimizer for Python code

Project description

GraphOptim

Graph-theoretic structural optimizer for Python code

Detects and fixes structural inefficiencies that rule-based linters cannot catch โ€” especially effective on AI-generated modules.

CI PyPI version Python versions License: MIT Code of Conduct Changelog


Why GraphOptim?

Production Python code โ€” whether written by AI assistants (Copilot, Claude, Cursor, Gemini) or humans โ€” often contains graph-level structural inefficiencies that traditional linters miss:

  • ๐Ÿ”ด Redundant execution paths โ€” duplicate conditional branches
  • ๐Ÿ’€ Dead code blocks โ€” unreachable code after returns/raises
  • ๐ŸŽฏ Over-centralized functions โ€” bottleneck nodes everything flows through
  • ๐Ÿ“ Inflated complexity โ€” unnecessarily deep execution chains

How is this different from existing tools?

Tool Approach Misses
flake8 / ruff Rule-based token patterns Graph-level redundancy, dead paths
pylint AST heuristics + rules Topological inefficiencies
SonarQube Rule-based + some metrics Graph-theoretic pass selection
GraphOptim Weighted CFG + graph algorithms + knapsack optimization โ€”

โšก Quickstart

Install

pip install graphoptim

30-Second Demo

import graphoptim as go

code = """
def process(items):
    results = []
    for item in items:
        if item > 0:
            results.append(item)
    return results
    print("unreachable")  # Dead code!
"""

# Analyze
report = go.analyze(code)
print(f"Score: {report.total_score}/100")
# โ†’ Score: 85/100

# Optimize
optimized = go.optimize(code, passes=["dead_code"])
# โ†’ Dead code removed, valid Python output

CLI

# Analyze a file
graphoptim analyze myfile.py

# Analyze with detailed metrics
graphoptim analyze myfile.py --verbose

# Show a diff of what would change, and auto-save the generated file 
# into a graphoptimized/ folder for review (recommended first step)
graphoptim optimize myfile.py --diff

# Show diff for an entire project
graphoptim optimize ./src --diff

# Optimize (preview mode โ€” prints full optimized code)
graphoptim optimize myfile.py

# Optimize in-place (creates .bak backup)
graphoptim optimize myfile.py --inplace

# Analyze an entire project
graphoptim analyze ./src

# Run the empirical benchmark
graphoptim benchmark --samples 100 --models claude,gpt4o,gemini

CLI Output Example

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ GraphOptim Analysis โ€” myfile.py                   โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
  Functions analyzed: 4
  Total optimization score: 62/100

process_data()       score: 45/100  โš  needs attention
โ”œโ”€ Cyclomatic complexity: 12   (threshold: 7)
โ”œโ”€ Dead nodes: 2               (unreachable at lines 34, 51)
โ”œโ”€ Betweenness bottleneck: 0.9 (line 22 is critical path bottleneck)
โ””โ”€ Suggested passes: dead_code, centrality_split

validate_input()     score: 88/100  โœ“ good
format_output()      score: 71/100  ~ acceptable
main()               score: 44/100  โš  needs attention

๐Ÿ“Š How It Works

GraphOptim treats your code as a graph problem:

Source Code โ†’ AST โ†’ Control Flow Graph (CFG) โ†’ Weighted DiGraph โ†’ Analysis + Optimization
  1. Parse โ€” Builds a CFG where nodes are basic blocks, edges are control flow transitions
  2. Analyze โ€” Extracts 7 graph metrics (cyclomatic complexity, dead nodes, CFG diameter, avg shortest path, betweenness centrality, node/edge ratio, LOC)
  3. Detect โ€” Pattern detectors identify dead nodes, redundant paths, bottlenecks, deep chains
  4. Select โ€” A 0/1 Knapsack solver selects the optimal subset of optimization passes within your risk budget
  5. Optimize โ€” Selected passes transform the AST, producing valid Python

๐Ÿ“– For full architecture details, see the How It Works wiki page.


๐Ÿ”ง Optimization Passes

Pass Detects Fixes Risk
dead_code Unreachable code after return/raise/break Removes dead AST nodes Low (0.2)
guard_clause Deeply nested if-blocks Refactors to early-return guards Med-Low (0.4)
unused_variable Assigned-but-never-read variables Removes safe unused assignments Low-Med (0.3)
constant_folding Constant arithmetic/string expressions Evaluates at parse time Very Low (0.1)
path_shortener Duplicate conditional branches Merges identical branches Medium (0.5)
centrality High-betweenness bottleneck nodes Suggests helper extraction Medium (0.6)

Knapsack Pass Selection

Instead of running all passes blindly, GraphOptim uses dynamic programming (0/1 Knapsack) to select the optimal subset:

from graphoptim.optimizer.passes.knapsack import KnapsackSelector, PassInfo

selector = KnapsackSelector(budget=0.6)  # max total risk = 0.6
result = selector.select(available_passes)
print(result.summary())

๐Ÿงฉ Want to add your own pass? See the Adding Passes guide.


๐Ÿ“ˆ Benchmark

GraphOptim includes a benchmark pipeline that empirically validates its core hypothesis against HumanEval and MBPP datasets using three LLM providers:

Provider Model API Key Env Var
Anthropic Claude Opus 4.6 ANTHROPIC_API_KEY
OpenAI GPT-5.2 OPENAI_API_KEY
Google Gemini 2.5 Pro GOOGLE_API_KEY
# Set API keys
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
export GOOGLE_API_KEY="AI..."

# Run benchmark
graphoptim benchmark --samples 100 --models claude,gpt4o,gemini

The benchmark produces:

  • benchmark_results.json โ€” Raw metrics for all functions
  • statistical_report.csv โ€” Mann-Whitney U test results
  • benchmark_report.md โ€” Human-readable findings with plots

๐Ÿ›  Development

# Clone and set up
git clone https://github.com/agodianel/Graphoptim-Code-Optimizer.git
cd graphoptim

# Install with uv (recommended)
uv pip install -e ".[dev,benchmark]"

# Run tests
uv run pytest tests/ -v

# Run linting
uv run ruff check .

# Run formatting
uv run black .

# Type checking
uv run mypy graphoptim/ --ignore-missing-imports

See CONTRIBUTING.md for the full contributing guide.


๐Ÿ“ Project Structure

graphoptim/
โ”œโ”€โ”€ parser/           # Source โ†’ Graph conversion
โ”‚   โ”œโ”€โ”€ cfg_builder   # Control Flow Graph builder
โ”‚   โ”œโ”€โ”€ dfg_builder   # Data Flow Graph builder
โ”‚   โ””โ”€โ”€ ast_utils     # AST helpers and node weighing
โ”œโ”€โ”€ analyzer/         # Graph โ†’ Insights
โ”‚   โ”œโ”€โ”€ metrics       # 7 graph metric extraction
โ”‚   โ”œโ”€โ”€ patterns      # Structural pattern detectors
โ”‚   โ””โ”€โ”€ reporter      # Scored report generation
โ”œโ”€โ”€ optimizer/        # Insights โ†’ Better Code
โ”‚   โ”œโ”€โ”€ passes/       # Individual optimization passes
โ”‚   โ”‚   โ”œโ”€โ”€ dead_code, path_shortener, centrality
โ”‚   โ”‚   โ””โ”€โ”€ knapsack  # 0/1 Knapsack pass selector
โ”‚   โ””โ”€โ”€ rewriter      # Pass orchestration + validation
โ”œโ”€โ”€ benchmark/        # Empirical validation pipeline
โ”œโ”€โ”€ cli.py            # Click + Rich CLI
โ””โ”€โ”€ config.py         # Configuration (env var loading)

๐Ÿ“‹ Links

๐Ÿ“ฆ PyPI pypi.org/project/graphoptim
๐Ÿ“– Wiki docs/wiki
๐Ÿ› Issues GitHub Issues
๐Ÿ“ Changelog CHANGELOG.md
๐Ÿ”’ Security SECURITY.md
๐Ÿค Contributing CONTRIBUTING.md
๐Ÿ“œ License MIT

License

MIT License โ€” See LICENSE for details.

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

graphoptim-0.1.0.tar.gz (240.0 kB view details)

Uploaded Source

Built Distribution

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

graphoptim-0.1.0-py3-none-any.whl (66.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: graphoptim-0.1.0.tar.gz
  • Upload date:
  • Size: 240.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for graphoptim-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5566605941e301d16a4299d45cbb361c7cb61137752222f3632cb8c14b13f25a
MD5 1f26765afe753b5792644dd366c76a15
BLAKE2b-256 c661c1fa34adb02e7858f6df84fdc2d6dee19df0bad503fe7ecbaad71c3e153b

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphoptim-0.1.0.tar.gz:

Publisher: publish.yml on agodianel/Graphoptim-Code-Optimizer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file graphoptim-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: graphoptim-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 66.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for graphoptim-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0e295f94fb358e07b01ec11712e1735a04539b8d5b56136a4ff50be6546345ab
MD5 312fc0a80b92eb12a6f8856b63cc8e61
BLAKE2b-256 79f0675d7a420a3f1060901991cdb4e65e12730516f56f345e03ee97becc785a

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphoptim-0.1.0-py3-none-any.whl:

Publisher: publish.yml on agodianel/Graphoptim-Code-Optimizer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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