@@ -10,7 +10,7 @@ Empirical complexity regression checker: run a target function across input size
1010[ ![ License: MIT] ( https://img.shields.io/badge/License-MIT-yellow.svg )] ( https://opensource.org/licenses/MIT )
1111[ ![ Downloads] ( https://img.shields.io/pypi/dm/bigocheck )] ( https://pypi.org/project/bigocheck/ )
1212[ ![ Zero Dependencies] ( https://img.shields.io/badge/dependencies-zero-green.svg )] ( )
13- [ ![ Tests] ( https://img.shields.io/badge/tests-116%2F116 %20passing-success )] ( )
13+ [ ![ Tests] ( https://img.shields.io/badge/tests-126%2F126 %20passing-success )] ( )
1414[ ![ Codacy Badge] ( https://app.codacy.com/project/badge/Grade/2eee22cbfa8443cda69af338e4e12a83 )] ( https://app.codacy.com/gh/adwantg/bigocheck/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade )
1515[ ![ Typed] ( https://img.shields.io/badge/typed-yes-blue.svg )] ( )
1616[ ![ Code style: black] ( https://img.shields.io/badge/code%20style-black-000000.svg )] ( https://github.com/psf/black )
@@ -42,7 +42,7 @@ print(analysis.best_label) # O(n²) ⚠️ Regression detected!
4242** Key Value** :
4343- ✅ ** Zero Dependencies** - No numpy, scipy, or matplotlib required
4444- ✅ ** CLI-First** - Use in CI/CD without writing code
45- - ✅ ** Production Ready** - 116/116 tests passing, v0.8 .0
45+ - ✅ ** Production Ready** - 126/126 tests passing, v1.1 .0
4646
4747---
4848
@@ -211,20 +211,25 @@ for fit in analysis.fits[:3]:
211211
212212### 2️⃣ Complexity Assertions (CI/CD Testing)
213213
214- Assert that functions have expected complexity. Perfect for CI/CD pipelines .
214+ Use ` assert_bounds() ` as the default guardrail for real-world CI, and ` assert_complexity() ` when you want an exact target class .
215215
216216``` python
217- from bigocheck import assert_complexity, ComplexityAssertionError
217+ from bigocheck import assert_bounds, assert_complexity, ComplexityAssertionError
218218
219- @assert_complexity ( " O(n )" , sizes = [ 100 , 500 , 1000 ] )
219+ @assert_bounds ( lower = " O(1 )" , upper = " O(n) " , profile = " ci " )
220220def linear_sum (n ):
221221 return sum (range (n))
222222
223223# First call triggers verification
224224linear_sum(10 ) # Passes silently
225225
226+ # Use assert_complexity when you need an exact class
227+ @assert_complexity (" O(n)" , profile = " ci" )
228+ def exact_linear (n ):
229+ return sum (range (n))
230+
226231# If complexity is wrong, raises ComplexityAssertionError
227- @assert_complexity (" O(1)" ) # Wrong!
232+ @assert_complexity (" O(1)" , profile = " ci " ) # Wrong!
228233def actually_linear (n ):
229234 return sum (range (n))
230235
@@ -382,31 +387,31 @@ analysis = benchmark_function(my_func, sizes=sizes)
382387
383388### 8️⃣ pytest Integration
384389
385- Use the pytest plugin for testing .
390+ Use the pytest plugin for test defaults and suite-level reporting .
386391
387392``` python
388- # In your test file
389393import pytest
390- from bigocheck.pytest_plugin import ComplexityChecker
391394
392- def test_with_fixture (complexity_checker ):
395+ pytest_plugins = [" bigocheck.pytest_plugin" ]
396+
397+
398+ @pytest.mark.complexity (" O(n)" , profile = " ci" , space_upper = " O(n)" )
399+ def test_with_marker_defaults (complexity_checker ):
393400 def my_func (n ):
394- return sum ( range (n))
395-
396- result = complexity_checker.check(my_func, expected = " O(n) " )
401+ return [ 0 ] * n
402+
403+ result = complexity_checker.check(my_func)
397404 assert result.passes, result.message
398405
399- def test_with_assertion (complexity_checker ):
406+ def test_with_explicit_bounds (complexity_checker ):
400407 def my_func (n ):
401408 return sum (range (n))
402-
403- # Raises ComplexityAssertionError if fails
404- complexity_checker.assert_complexity(my_func, " O(n)" )
409+
410+ complexity_checker.assert_bounds(my_func, upper = " O(n)" )
405411```
406412
407- ** Register the plugin in conftest.py:**
408- ``` python
409- pytest_plugins = [" bigocheck.pytest_plugin" ]
413+ ``` bash
414+ pytest -q --bigocheck-report .artifacts/bigocheck-report.json
410415```
411416
412417---
@@ -430,6 +435,16 @@ analysis = benchmark_function(
430435)
431436```
432437
438+ If object construction should be excluded from the timed region, use ` setup= ` instead:
439+
440+ ``` python
441+ analysis = benchmark_function(
442+ my_sort,
443+ sizes = [1000 , 5000 , 10000 ],
444+ setup = lambda n : ((integers(n),), {}),
445+ )
446+ ```
447+
433448** Available generators:**
434449
435450| Generator | Description |
@@ -1027,7 +1042,7 @@ from bigocheck import benchmark_with_profile, profile_decorator
10271042
10281043# Use a preset profile
10291044analysis = benchmark_with_profile(my_func, profile = " accurate" )
1030- # Profiles: fast, balanced, accurate, thorough, large, small
1045+ # Profiles: fast, balanced, accurate, thorough, large, small, ci
10311046
10321047# Decorator usage
10331048@profile_decorator (" fast" )
@@ -1037,6 +1052,8 @@ def check_me(n):
10371052check_me(100 ) # Prints: 📊 check_me: O(1)
10381053```
10391054
1055+ ` profile="ci" ` is the recommended default for automated checks: larger sizes, more trials, warmup, and robust aggregation.
1056+
10401057---
10411058
10421059### 3️⃣2️⃣ Auto Documentation
0 commit comments