Skip to content

Commit 4f35c61

Browse files
committed
space complexity and other features push
1 parent 009ba09 commit 4f35c61

14 files changed

Lines changed: 1161 additions & 36 deletions

File tree

.github/workflows/complexity.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# bigocheck Complexity Analysis Workflow
2+
# Author: gadwant
3+
#
4+
# This workflow runs complexity analysis on your codebase
5+
# and detects regressions in time/space complexity.
6+
#
7+
# Usage:
8+
# 1. Copy this file to .github/workflows/complexity.yml
9+
# 2. Configure target functions in the matrix
10+
# 3. Optionally save baselines for regression detection
11+
12+
name: Complexity Analysis
13+
14+
on:
15+
push:
16+
branches: [main, master]
17+
pull_request:
18+
branches: [main, master]
19+
20+
jobs:
21+
complexity-check:
22+
runs-on: ubuntu-latest
23+
24+
strategy:
25+
matrix:
26+
python-version: ['3.11']
27+
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- name: Set up Python ${{ matrix.python-version }}
32+
uses: actions/setup-python@v5
33+
with:
34+
python-version: ${{ matrix.python-version }}
35+
36+
- name: Install dependencies
37+
run: |
38+
python -m pip install --upgrade pip
39+
pip install bigocheck
40+
# Install your project
41+
pip install -e .
42+
43+
- name: Run complexity analysis
44+
run: |
45+
# Example: Analyze your functions
46+
# bigocheck run --target mymodule:myfunc --sizes 100 500 1000 --json > results.json
47+
echo "Add your complexity checks here"
48+
49+
# Optional: Regression detection against baseline
50+
# - name: Check for regressions
51+
# run: |
52+
# python -c "
53+
# from bigocheck import benchmark_function, load_baseline, detect_regression
54+
# from mymodule import my_function
55+
#
56+
# current = benchmark_function(my_function, sizes=[100, 500, 1000])
57+
# baseline = load_baseline('baselines/my_function.json')
58+
# result = detect_regression(current, baseline, time_threshold=0.2)
59+
#
60+
# if result.has_regression:
61+
# print('❌ REGRESSION DETECTED')
62+
# print(result.message)
63+
# exit(1)
64+
# print('✅ No regressions detected')
65+
# "
66+
67+
# Optional: Save baseline on main branch
68+
# save-baseline:
69+
# runs-on: ubuntu-latest
70+
# if: github.ref == 'refs/heads/main' && github.event_name == 'push'
71+
#
72+
# steps:
73+
# - uses: actions/checkout@v4
74+
#
75+
# - name: Set up Python
76+
# uses: actions/setup-python@v5
77+
# with:
78+
# python-version: '3.11'
79+
#
80+
# - name: Install and save baseline
81+
# run: |
82+
# pip install bigocheck -e .
83+
# python -c "
84+
# from bigocheck import benchmark_function, save_baseline
85+
# from mymodule import my_function
86+
#
87+
# analysis = benchmark_function(my_function, sizes=[100, 500, 1000], memory=True)
88+
# save_baseline(analysis, 'baselines/my_function.json', name='${{ github.sha }}')
89+
# "
90+
#
91+
# - name: Commit baseline
92+
# uses: stefanzweifel/git-auto-commit-action@v5
93+
# with:
94+
# commit_message: "Update complexity baseline"
95+
# file_pattern: "baselines/*.json"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ dist/
1010
build/
1111
*.egg-info/
1212
.DS_Store
13+
release.sh

README.md

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,23 @@ Empirical complexity regression checker: run a target function across input size
1616

1717
| Feature | Description |
1818
|---------|-------------|
19-
| **🧮 Complexity Fitting** | Fits to 9 classes: O(1), O(log n), O(√n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!) |
19+
| **🧮 Time Complexity** | Fits to 9 classes: O(1), O(log n), O(√n), O(n), O(n log n), O(n²), O(n³), O(2ⁿ), O(n!) |
20+
| **📐 Space Complexity** | Classifies memory usage to complexity classes (O(1), O(n), O(n²), etc.) |
21+
| **📊 Statistical Significance** | P-values to validate complexity classification |
22+
| **🔄 Regression Detection** | Save baselines and detect performance regressions in CI/CD |
23+
| **📉 Best/Worst/Avg Cases** | Analyze with sorted, reversed, and random inputs |
2024
| **✅ Complexity Assertions** | `@assert_complexity("O(n)")` decorator for CI/CD testing |
2125
| **🔍 Bounds Verification** | `verify_bounds()` to check if function meets expected complexity |
2226
| **📊 Confidence Scoring** | Know how reliable your results are |
2327
| **🔀 A/B Comparison** | Compare two implementations head-to-head |
2428
| **📄 Report Generation** | Generate markdown reports automatically |
2529
| **🔧 pytest Plugin** | Integration with pytest for testing |
2630
| **📈 Plotting** | Optional matplotlib visualization |
27-
| **💾 Memory Profiling** | Track peak memory usage |
31+
| **💾 Memory Profiling** | Track peak memory usage with `--memory` flag |
2832
| **🚀 Auto Size Selection** | Automatically choose optimal input sizes |
2933
| **📦 Zero Dependencies** | Pure standard library, no numpy required |
3034
| **💻 CLI-First** | Full command-line interface |
35+
| **⚙️ GitHub Actions** | Pre-built CI workflow template |
3136

3237
---
3338

@@ -336,17 +341,32 @@ analysis = benchmark_function(
336341

337342
---
338343

339-
### 🔟 Memory Profiling
344+
### 🔟 Memory & Space Complexity
340345

341-
Track peak memory usage.
346+
Track memory usage and automatically classify space complexity.
342347

343348
```bash
344349
bigocheck run --target mymodule:myfunc --sizes 1000 5000 10000 --memory
345350
```
346351

352+
**Example Output:**
353+
```
354+
Time Complexity: O(n)
355+
Space Complexity: O(n)
356+
357+
Measurements:
358+
n=1000 time=0.001234s ±0.000001s mem=81,920B
359+
n=5000 time=0.006789s ±0.000005s mem=409,600B
360+
n=10000 time=0.012345s ±0.000012s mem=819,200B
361+
```
362+
363+
**Library Usage:**
347364
```python
348365
analysis = benchmark_function(my_func, sizes=[1000, 5000, 10000], memory=True)
349366

367+
print(f"Time Complexity: {analysis.best_label}")
368+
print(f"Space Complexity: {analysis.space_label}")
369+
350370
for m in analysis.measurements:
351371
print(f"n={m.size}: {m.seconds:.4f}s, memory={m.memory_bytes:,} bytes")
352372
```
@@ -442,6 +462,21 @@ from bigocheck import (
442462
VerificationResult,
443463
ComparisonResult,
444464
ConfidenceResult,
465+
466+
# Statistics
467+
SignificanceResult,
468+
compute_significance,
469+
470+
# Regression
471+
Baseline,
472+
RegressionResult,
473+
save_baseline,
474+
load_baseline,
475+
detect_regression,
476+
477+
# Case Analysis
478+
CasesAnalysis,
479+
analyze_cases,
445480
)
446481
```
447482

@@ -458,9 +493,13 @@ bigocheck/
458493
│ ├── assertions.py # Assertions and verification
459494
│ ├── compare.py # A/B comparison
460495
│ ├── reports.py # Report generation
496+
│ ├── statistics.py # P-values and significance
497+
│ ├── regression.py # Baseline save/load, regression detection
498+
│ ├── cases.py # Best/worst/average case analysis
461499
│ ├── datagen.py # Data generators
462500
│ ├── plotting.py # Optional plotting
463501
│ └── pytest_plugin.py # pytest integration
502+
├── .github/workflows/ # CI/CD templates
464503
├── tests/ # Test suite
465504
├── pyproject.toml
466505
└── LICENSE
@@ -477,6 +516,7 @@ pytest -v
477516

478517
---
479518

519+
480520
## 📄 License
481521

482522
MIT — see [LICENSE](LICENSE).

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Author: gadwant
22
[project]
33
name = "bigocheck"
4-
version = "0.2.0"
4+
version = "0.4.0"
55
description = "Zero-dependency empirical Big-O complexity checker for Python with CLI, assertions, and pytest integration"
66
readme = "README.md"
77
requires-python = ">=3.9"

src/bigocheck/__init__.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
Measurement,
1111
benchmark_function,
1212
fit_complexities,
13+
fit_space_complexity,
1314
complexity_basis,
1415
resolve_callable,
1516
)
@@ -40,6 +41,31 @@
4041
save_report,
4142
)
4243

44+
# Statistics (p-values)
45+
from .statistics import (
46+
SignificanceResult,
47+
compute_significance,
48+
format_significance,
49+
)
50+
51+
# Regression detection
52+
from .regression import (
53+
Baseline,
54+
RegressionResult,
55+
save_baseline,
56+
load_baseline,
57+
detect_regression,
58+
compare_to_baseline_file,
59+
)
60+
61+
# Case analysis (best/worst/avg)
62+
from .cases import (
63+
CaseResult,
64+
CasesAnalysis,
65+
analyze_cases,
66+
format_cases_result,
67+
)
68+
4369
__all__ = [
4470
# Version
4571
"__version__",
@@ -49,6 +75,7 @@
4975
"Measurement",
5076
"benchmark_function",
5177
"fit_complexities",
78+
"fit_space_complexity",
5279
"complexity_basis",
5380
"resolve_callable",
5481
# Assertions
@@ -68,6 +95,22 @@
6895
"generate_comparison_report",
6996
"generate_verification_report",
7097
"save_report",
98+
# Statistics
99+
"SignificanceResult",
100+
"compute_significance",
101+
"format_significance",
102+
# Regression
103+
"Baseline",
104+
"RegressionResult",
105+
"save_baseline",
106+
"load_baseline",
107+
"detect_regression",
108+
"compare_to_baseline_file",
109+
# Cases
110+
"CaseResult",
111+
"CasesAnalysis",
112+
"analyze_cases",
113+
"format_cases_result",
71114
]
72115

73-
__version__ = "0.2.0"
116+
__version__ = "0.4.0"

0 commit comments

Comments
 (0)