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.
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
- Parse โ Builds a CFG where nodes are basic blocks, edges are control flow transitions
- Analyze โ Extracts 7 graph metrics (cyclomatic complexity, dead nodes, CFG diameter, avg shortest path, betweenness centrality, node/edge ratio, LOC)
- Detect โ Pattern detectors identify dead nodes, redundant paths, bottlenecks, deep chains
- Select โ A 0/1 Knapsack solver selects the optimal subset of optimization passes within your risk budget
- 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 |
| 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 functionsstatistical_report.csvโ Mann-Whitney U test resultsbenchmark_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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5566605941e301d16a4299d45cbb361c7cb61137752222f3632cb8c14b13f25a
|
|
| MD5 |
1f26765afe753b5792644dd366c76a15
|
|
| BLAKE2b-256 |
c661c1fa34adb02e7858f6df84fdc2d6dee19df0bad503fe7ecbaad71c3e153b
|
Provenance
The following attestation bundles were made for graphoptim-0.1.0.tar.gz:
Publisher:
publish.yml on agodianel/Graphoptim-Code-Optimizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphoptim-0.1.0.tar.gz -
Subject digest:
5566605941e301d16a4299d45cbb361c7cb61137752222f3632cb8c14b13f25a - Sigstore transparency entry: 1264900324
- Sigstore integration time:
-
Permalink:
agodianel/Graphoptim-Code-Optimizer@b756d1d3a0b8649bb266cf107185efe6e8a94d59 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/agodianel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b756d1d3a0b8649bb266cf107185efe6e8a94d59 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e295f94fb358e07b01ec11712e1735a04539b8d5b56136a4ff50be6546345ab
|
|
| MD5 |
312fc0a80b92eb12a6f8856b63cc8e61
|
|
| BLAKE2b-256 |
79f0675d7a420a3f1060901991cdb4e65e12730516f56f345e03ee97becc785a
|
Provenance
The following attestation bundles were made for graphoptim-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on agodianel/Graphoptim-Code-Optimizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphoptim-0.1.0-py3-none-any.whl -
Subject digest:
0e295f94fb358e07b01ec11712e1735a04539b8d5b56136a4ff50be6546345ab - Sigstore transparency entry: 1264900402
- Sigstore integration time:
-
Permalink:
agodianel/Graphoptim-Code-Optimizer@b756d1d3a0b8649bb266cf107185efe6e8a94d59 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/agodianel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b756d1d3a0b8649bb266cf107185efe6e8a94d59 -
Trigger Event:
release
-
Statement type: