ovld 0.4.4__tar.gz → 0.4.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ovld-0.4.4 → ovld-0.4.6}/.github/workflows/python-package.yml +3 -0
- ovld-0.4.6/.python-version +1 -0
- {ovld-0.4.4 → ovld-0.4.6}/PKG-INFO +11 -10
- {ovld-0.4.4 → ovld-0.4.6}/README.md +10 -9
- ovld-0.4.6/beary.py +120 -0
- {ovld-0.4.4 → ovld-0.4.6}/bench.py +32 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_calc.py +1 -1
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_multer.py +1 -1
- ovld-0.4.6/benchmarks/test_regexp.py +96 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_tuple.py +3 -0
- ovld-0.4.6/benchmarks/test_typechecking.py +160 -0
- {ovld-0.4.4 → ovld-0.4.6}/docs/compare.md +14 -13
- {ovld-0.4.4 → ovld-0.4.6}/gen_comparison_table.py +12 -2
- ovld-0.4.6/gen_typecheck_table.py +60 -0
- ovld-0.4.6/ichk.py +39 -0
- ovld-0.4.6/kraken.py +30 -0
- {ovld-0.4.4 → ovld-0.4.6}/pyproject.toml +1 -1
- {ovld-0.4.4 → ovld-0.4.6}/reddit.md +7 -6
- ovld-0.4.6/refun.py +16 -0
- ovld-0.4.6/reper.py +6 -0
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/__init__.py +0 -2
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/core.py +186 -191
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/dependent.py +59 -26
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/mro.py +5 -0
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/recode.py +64 -75
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/types.py +11 -7
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/utils.py +47 -0
- ovld-0.4.6/src/ovld/version.py +1 -0
- ovld-0.4.6/tests/__init__.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_dependent.py +4 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_method_doc.txt +1 -1
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld.py +34 -43
- {ovld-0.4.4 → ovld-0.4.6}/typo.py +13 -2
- {ovld-0.4.4 → ovld-0.4.6}/uv.lock +1 -1
- ovld-0.4.4/.python-version +0 -1
- ovld-0.4.4/beary.py +0 -30
- ovld-0.4.4/src/ovld/version.py +0 -1
- {ovld-0.4.4 → ovld-0.4.6}/.bsync-snap-20220324145902.852076 +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/.bsync-snap-20240916114026.355340 +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/.envrc +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/.gitignore +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/.readthedocs.yaml +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/LICENSE +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/add.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/anal.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/bench/requirements.txt +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchd.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/__init__.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/common.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_add.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_ast.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_fib.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_trivial.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_tweaknum.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/cloz.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/coco.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/data.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/didi.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/docs/dependent.md +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/docs/features.md +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/docs/index.md +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/docs/types.md +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/docs/usage.md +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/doo.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/edges.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/explore.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/facto.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/gentest.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/hello.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/hntest.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/klos.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/mkdocs.yml +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/nxt.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.0-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.0.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.1-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.1.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.2-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.2.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.3-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.3.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.4-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.4.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.5-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.5.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.6-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.6.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.7-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.7.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.8-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.8.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.9-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.9.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.0-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.0.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.1-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.1.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.10-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.10.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.11-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.11.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.2-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.2.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.3-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.3.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.4-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.4.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.5-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.5.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.6-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.6.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.7-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.7.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.8-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.8.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.9-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.9.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.0-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.0.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.1-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.1.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.2-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.2.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.3-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.3.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.4-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.4.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.5-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.5.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.8-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.8.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.9-py3-none-any.whl +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.9.tar.gz +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/one_two_three.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/outoftheway.toml +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/reddit.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/abc.py +0 -0
- /ovld-0.4.4/tests/__init__.py → /ovld-0.4.6/src/ovld/py.typed +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/src/ovld/typemap.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/stuff.md +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tb.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tensor.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/modules/gingerbread.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_abc.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_examples.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_global.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_mro.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_display.txt +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_display_more.txt +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_doc.txt +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_doc2.txt +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_typemap.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_types.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/tests/test_utils.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/todo.q +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/toot.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/world.yaml +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/x.py +0 -0
- {ovld-0.4.4 → ovld-0.4.6}/zaggo +0 -0
@@ -40,6 +40,8 @@ jobs:
|
|
40
40
|
- python: '3.11'
|
41
41
|
coverage: false
|
42
42
|
- python: '3.12'
|
43
|
+
coverage: false
|
44
|
+
- python: '3.13'
|
43
45
|
coverage: true
|
44
46
|
steps:
|
45
47
|
- name: Check out the code
|
@@ -70,6 +72,7 @@ jobs:
|
|
70
72
|
- python: '3.10'
|
71
73
|
- python: '3.11'
|
72
74
|
- python: '3.12'
|
75
|
+
- python: '3.13'
|
73
76
|
steps:
|
74
77
|
- name: Check out the code
|
75
78
|
uses: actions/checkout@v3
|
@@ -0,0 +1 @@
|
|
1
|
+
3.13
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: ovld
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.6
|
4
4
|
Summary: Overloading Python functions
|
5
5
|
Project-URL: Homepage, https://ovld.readthedocs.io/en/latest/
|
6
6
|
Project-URL: Documentation, https://ovld.readthedocs.io/en/latest/
|
@@ -201,16 +201,17 @@ assert Two().f("s") == "a string"
|
|
201
201
|
|
202
202
|
# Benchmarks
|
203
203
|
|
204
|
-
`ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it
|
204
|
+
`ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it has 1.5x to 100x less overhead.
|
205
205
|
|
206
206
|
Time relative to the fastest implementation (1.00) (lower is better).
|
207
207
|
|
208
|
-
|
|
208
|
+
| Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch/) | [runtype](https://github.com/erezsh/runtype) | [fastcore](https://github.com/fastai/fastcore) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
|
209
209
|
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
210
|
-
|[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.
|
211
|
-
|[
|
212
|
-
|[
|
213
|
-
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.
|
214
|
-
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.
|
215
|
-
|[
|
216
|
-
|[
|
210
|
+
|[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|51.93|1.91|
|
211
|
+
|[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|46.74|7.32|
|
212
|
+
|[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|59.31|x|
|
213
|
+
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|28.39|1.66|
|
214
|
+
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|x|
|
215
|
+
|[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|x|
|
216
|
+
|[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|x|
|
217
|
+
|[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|x|
|
@@ -188,16 +188,17 @@ assert Two().f("s") == "a string"
|
|
188
188
|
|
189
189
|
# Benchmarks
|
190
190
|
|
191
|
-
`ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it
|
191
|
+
`ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it has 1.5x to 100x less overhead.
|
192
192
|
|
193
193
|
Time relative to the fastest implementation (1.00) (lower is better).
|
194
194
|
|
195
|
-
|
|
195
|
+
| Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch/) | [runtype](https://github.com/erezsh/runtype) | [fastcore](https://github.com/fastai/fastcore) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
|
196
196
|
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
197
|
-
|[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.
|
198
|
-
|[
|
199
|
-
|[
|
200
|
-
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.
|
201
|
-
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.
|
202
|
-
|[
|
203
|
-
|[
|
197
|
+
|[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|51.93|1.91|
|
198
|
+
|[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|46.74|7.32|
|
199
|
+
|[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|59.31|x|
|
200
|
+
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|28.39|1.66|
|
201
|
+
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|x|
|
202
|
+
|[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|x|
|
203
|
+
|[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|x|
|
204
|
+
|[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|x|
|
ovld-0.4.6/beary.py
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
import timeit
|
2
|
+
from dataclasses import dataclass
|
3
|
+
|
4
|
+
from beartype import (
|
5
|
+
BeartypeConf, # <-- this isn't your fault
|
6
|
+
beartype,
|
7
|
+
)
|
8
|
+
from beartype.claw import (
|
9
|
+
beartype_all,
|
10
|
+
) # <-- you didn't sign up for this
|
11
|
+
from strongtyping.strong_typing import match_typing
|
12
|
+
from typeguard import typechecked
|
13
|
+
|
14
|
+
# from enforce import runtime_validation
|
15
|
+
from ovld import ovld
|
16
|
+
|
17
|
+
# from ovld.check import typecheck
|
18
|
+
|
19
|
+
beartype_all(conf=BeartypeConf())
|
20
|
+
# beartype_this_package() # <-- raise exceptions in your code
|
21
|
+
# beartype_all(conf=BeartypeConf(violation_type=UserWarning))
|
22
|
+
|
23
|
+
|
24
|
+
@beartype
|
25
|
+
def f_bear(x: int, y: int):
|
26
|
+
return x + y
|
27
|
+
|
28
|
+
|
29
|
+
@ovld
|
30
|
+
def f_ovld(x: int, y: int):
|
31
|
+
return x + y
|
32
|
+
|
33
|
+
|
34
|
+
@ovld
|
35
|
+
def f_ovld_D(x: int, y: int):
|
36
|
+
# breakpoint()
|
37
|
+
return x + y
|
38
|
+
|
39
|
+
|
40
|
+
@match_typing
|
41
|
+
def f_strong(x: int, y: int):
|
42
|
+
return x + y
|
43
|
+
|
44
|
+
|
45
|
+
@typechecked
|
46
|
+
def f_guard(x: int, y: int):
|
47
|
+
return x + y
|
48
|
+
|
49
|
+
|
50
|
+
# @runtime_validation
|
51
|
+
# def f_enforce(x: int, y: int):
|
52
|
+
# return x + y
|
53
|
+
|
54
|
+
|
55
|
+
def f_custom(x: int, y: int):
|
56
|
+
assert isinstance(x, int) and isinstance(y, int)
|
57
|
+
return x + y
|
58
|
+
|
59
|
+
|
60
|
+
class digdug(dict):
|
61
|
+
pass
|
62
|
+
|
63
|
+
|
64
|
+
def adder(x, y):
|
65
|
+
return x + y
|
66
|
+
|
67
|
+
|
68
|
+
didi = digdug({int: adder})
|
69
|
+
didi2 = digdug({(int, int): adder})
|
70
|
+
|
71
|
+
|
72
|
+
@dataclass
|
73
|
+
class Poop:
|
74
|
+
didi: dict
|
75
|
+
|
76
|
+
|
77
|
+
poo2 = Poop(didi2)
|
78
|
+
|
79
|
+
|
80
|
+
def f_custom_2(x: int, y: int):
|
81
|
+
assert didi2[type(x), type(y)]
|
82
|
+
return x + y
|
83
|
+
|
84
|
+
|
85
|
+
# def f_custom_2(x: int, y: int):
|
86
|
+
# func = didi[type(x)] and didi[type(y)]
|
87
|
+
# return func(x, y)
|
88
|
+
|
89
|
+
|
90
|
+
class Gusto:
|
91
|
+
def __init__(self, didi):
|
92
|
+
self.didi = didi
|
93
|
+
self.__name__ = "gusto"
|
94
|
+
|
95
|
+
def __call__(self, x: int, y: int):
|
96
|
+
func = self.didi[type(x), type(y)]
|
97
|
+
return func(x, y)
|
98
|
+
|
99
|
+
|
100
|
+
# f_bear(7, 8)
|
101
|
+
# f_ovld("a", 3)
|
102
|
+
# assert f_ovld(3, 4) == 7
|
103
|
+
|
104
|
+
|
105
|
+
for fn in (
|
106
|
+
f_bear,
|
107
|
+
f_strong,
|
108
|
+
f_guard,
|
109
|
+
f_ovld_D,
|
110
|
+
f_ovld,
|
111
|
+
f_custom,
|
112
|
+
f_custom_2,
|
113
|
+
Gusto(didi2),
|
114
|
+
Gusto(didi2).__call__,
|
115
|
+
):
|
116
|
+
timing = timeit.timeit(stmt=lambda: fn(3, 4), number=300000)
|
117
|
+
print(f"{fn.__name__:10}{1000 * timing:>10.3f}ms")
|
118
|
+
|
119
|
+
breakpoint()
|
120
|
+
f_ovld(4, 5)
|
@@ -4,6 +4,7 @@ from multimethod import multimethod
|
|
4
4
|
from multipledispatch import dispatch
|
5
5
|
from plum import dispatch as plum
|
6
6
|
|
7
|
+
# from strongtyping_pyoverload import overload
|
7
8
|
from ovld import ovld, recurse
|
8
9
|
|
9
10
|
# OVLD
|
@@ -157,6 +158,35 @@ def smap_pl(x: object, y: object):
|
|
157
158
|
return x + y
|
158
159
|
|
159
160
|
|
161
|
+
# # strongtyping
|
162
|
+
|
163
|
+
|
164
|
+
# @overload
|
165
|
+
# def smap_wh(x: list, y: list):
|
166
|
+
# """Three."""
|
167
|
+
# return [smap_wh(a, b) for a, b in zip(x, y)]
|
168
|
+
|
169
|
+
|
170
|
+
# @overload
|
171
|
+
# def smap_wh(x: tuple, y: tuple):
|
172
|
+
# return tuple(smap_wh(a, b) for a, b in zip(x, y))
|
173
|
+
|
174
|
+
|
175
|
+
# @overload
|
176
|
+
# def smap_wh(x: dict, y: dict):
|
177
|
+
# return {k: smap_wh(v, y[k]) for k, v in x.items()}
|
178
|
+
|
179
|
+
|
180
|
+
# @overload
|
181
|
+
# def smap_wh(x: object, y: object):
|
182
|
+
# return x + y
|
183
|
+
|
184
|
+
|
185
|
+
# @overload
|
186
|
+
# def smap_wh(x: str, y: str):
|
187
|
+
# return x + y
|
188
|
+
|
189
|
+
|
160
190
|
###
|
161
191
|
|
162
192
|
|
@@ -171,6 +201,7 @@ results = {
|
|
171
201
|
"smap_ii": smap_ii(A, B),
|
172
202
|
"smap_mh": smap_mh(A, B),
|
173
203
|
"smap_c": smap_c(A, B),
|
204
|
+
# "smap_wh": smap_wh(A, B),
|
174
205
|
}
|
175
206
|
|
176
207
|
expected = results["smap"]
|
@@ -186,5 +217,6 @@ print("smap_md\t", 10 * timeit.timeit(lambda: smap_md(A, B), number=10000))
|
|
186
217
|
print("smap_pl\t", 10 * timeit.timeit(lambda: smap_pl(A, B), number=10000))
|
187
218
|
print("smap_ov\t", 10 * timeit.timeit(lambda: smap(A, B), number=10000))
|
188
219
|
print("smap_c\t", 10 * timeit.timeit(lambda: smap_c(A, B), number=10000))
|
220
|
+
# print("smap_wh\t", 10 * timeit.timeit(lambda: smap_wh(A, B), number=10000))
|
189
221
|
print("smap_ii\t", 10 * timeit.timeit(lambda: smap_ii(A, B), number=10000))
|
190
222
|
print("smap_mh\t", 10 * timeit.timeit(lambda: smap_mh(A, B), number=10000))
|
@@ -148,7 +148,7 @@ def make_test(cls):
|
|
148
148
|
|
149
149
|
|
150
150
|
test_multer_ovld = make_test(make_multer(ovld_dispatch))
|
151
|
-
|
151
|
+
test_multer_recurse = make_test(OvldRecurseMulter)
|
152
152
|
test_multer_plum = make_test(make_multer(plum_dispatch))
|
153
153
|
test_multer_multimethod = make_test(make_multer(multimethod_dispatch))
|
154
154
|
test_multer_singledispatch = make_test(SingleDispatchMulter)
|
@@ -0,0 +1,96 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from ovld.dependent import Regexp
|
6
|
+
|
7
|
+
from .common import ovld_dispatch, plum_dispatch
|
8
|
+
|
9
|
+
###############################
|
10
|
+
# multiple dispatch libraries #
|
11
|
+
###############################
|
12
|
+
|
13
|
+
|
14
|
+
def make_regexp(dispatch):
|
15
|
+
@dispatch
|
16
|
+
def regexp(x: Regexp[r"^a"]):
|
17
|
+
return "one"
|
18
|
+
|
19
|
+
@dispatch
|
20
|
+
def regexp(x: Regexp[r"^[bcd]"]):
|
21
|
+
return "two"
|
22
|
+
|
23
|
+
@dispatch
|
24
|
+
def regexp(x: Regexp[r"end$"]):
|
25
|
+
return "three"
|
26
|
+
|
27
|
+
return regexp
|
28
|
+
|
29
|
+
|
30
|
+
##############
|
31
|
+
# isinstance #
|
32
|
+
##############
|
33
|
+
|
34
|
+
|
35
|
+
def regexp_search(x):
|
36
|
+
if re.search(string=x, pattern=r"^a"):
|
37
|
+
return "one"
|
38
|
+
if re.search(string=x, pattern=r"^[bcd]"):
|
39
|
+
return "two"
|
40
|
+
if re.search(string=x, pattern=r"end$"):
|
41
|
+
return "three"
|
42
|
+
|
43
|
+
|
44
|
+
re1 = re.compile(r"^a")
|
45
|
+
re2 = re.compile(r"^[bcd]")
|
46
|
+
re3 = re.compile(r"end$")
|
47
|
+
|
48
|
+
|
49
|
+
def regexp_compiled(x):
|
50
|
+
if re1.search(x):
|
51
|
+
return "one"
|
52
|
+
if re2.search(x):
|
53
|
+
return "two"
|
54
|
+
if re3.search(x):
|
55
|
+
return "three"
|
56
|
+
|
57
|
+
|
58
|
+
def regexp_compiled_nonexclusive(x):
|
59
|
+
r1 = bool(re1.search(x))
|
60
|
+
r2 = bool(re2.search(x))
|
61
|
+
r3 = bool(re3.search(x))
|
62
|
+
if r1:
|
63
|
+
return "one"
|
64
|
+
if r2:
|
65
|
+
return "two"
|
66
|
+
if r3:
|
67
|
+
return "three"
|
68
|
+
|
69
|
+
|
70
|
+
####################
|
71
|
+
# Test definitions #
|
72
|
+
####################
|
73
|
+
|
74
|
+
|
75
|
+
def make_test(fn):
|
76
|
+
@pytest.mark.benchmark(group="regexp")
|
77
|
+
def test(benchmark):
|
78
|
+
def run():
|
79
|
+
return [
|
80
|
+
fn("allo"),
|
81
|
+
fn("canada"),
|
82
|
+
fn("the end"),
|
83
|
+
]
|
84
|
+
|
85
|
+
result = benchmark(run)
|
86
|
+
assert result == ["one", "two", "three"]
|
87
|
+
|
88
|
+
return test
|
89
|
+
|
90
|
+
|
91
|
+
test_regexp_ovld = make_test(make_regexp(ovld_dispatch))
|
92
|
+
test_regexp_plum = make_test(make_regexp(plum_dispatch))
|
93
|
+
|
94
|
+
test_regexp_custom_search = make_test(regexp_search)
|
95
|
+
test_regexp_custom_compiled = make_test(regexp_compiled)
|
96
|
+
# test_regexp_custom_compiled_nx = make_test(regexp_compiled_nonexclusive)
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# from collections.abc import Collection
|
2
|
+
# from dataclasses import dataclass
|
3
|
+
# from itertools import product
|
4
|
+
# from numbers import Number
|
5
|
+
# from typing import Literal
|
6
|
+
|
7
|
+
# import pytest
|
8
|
+
# from beartype import beartype
|
9
|
+
|
10
|
+
# try:
|
11
|
+
# from strongtyping.strong_typing import match_typing
|
12
|
+
# except ImportError:
|
13
|
+
# match_typing = None
|
14
|
+
# from typeguard import typechecked
|
15
|
+
|
16
|
+
# from ovld import Ovld, ovld
|
17
|
+
# from ovld.dependent import Dependent, Regexp
|
18
|
+
# from ovld.types import Dataclass
|
19
|
+
|
20
|
+
|
21
|
+
# @dataclass
|
22
|
+
# class Point:
|
23
|
+
# x: int
|
24
|
+
# y: int
|
25
|
+
|
26
|
+
|
27
|
+
# def ovld(fn):
|
28
|
+
# o = Ovld()
|
29
|
+
# o.register(fn)
|
30
|
+
# return o.dispatch
|
31
|
+
|
32
|
+
|
33
|
+
# def typecheck_test(cases, checkers):
|
34
|
+
# def deco(fn):
|
35
|
+
# def make_test(chk_name, case_name, typecheck, params):
|
36
|
+
# group = f"{fn.__name__}_{case_name}"
|
37
|
+
|
38
|
+
# @pytest.mark.benchmark(group=group)
|
39
|
+
# def test(benchmark):
|
40
|
+
# *args, out = params
|
41
|
+
# tfn = typecheck(fn)
|
42
|
+
# result = benchmark(tfn, *args)
|
43
|
+
# assert result == out
|
44
|
+
|
45
|
+
# test.__name__ = f"test_{group}[{chk_name}]"
|
46
|
+
# globals()[test.__name__] = test
|
47
|
+
|
48
|
+
# for (case_name, case), (chk_name, chk) in product(
|
49
|
+
# cases.items(), checkers.items()
|
50
|
+
# ):
|
51
|
+
# if chk is not None:
|
52
|
+
# make_test(chk_name, case_name, chk, case)
|
53
|
+
|
54
|
+
# return deco
|
55
|
+
|
56
|
+
|
57
|
+
# @typecheck_test(
|
58
|
+
# cases=dict(normal=(10, 20, 200)),
|
59
|
+
# checkers=dict(
|
60
|
+
# ovld=ovld,
|
61
|
+
# beartype=beartype,
|
62
|
+
# typeguard=typechecked,
|
63
|
+
# strongtyping=match_typing,
|
64
|
+
# ),
|
65
|
+
# )
|
66
|
+
# def mul(x: int, y: int):
|
67
|
+
# return x * y
|
68
|
+
|
69
|
+
|
70
|
+
# @typecheck_test(
|
71
|
+
# cases=dict(
|
72
|
+
# ints=(10, 20, 30),
|
73
|
+
# lists=([1], [2], [1, 2]),
|
74
|
+
# ),
|
75
|
+
# checkers=dict(
|
76
|
+
# ovld=ovld,
|
77
|
+
# beartype=beartype,
|
78
|
+
# typeguard=typechecked,
|
79
|
+
# strongtyping=match_typing,
|
80
|
+
# ),
|
81
|
+
# )
|
82
|
+
# def add(x: int | str | float | list, y: int | str | float | list):
|
83
|
+
# return x + y
|
84
|
+
|
85
|
+
|
86
|
+
# @typecheck_test(
|
87
|
+
# cases=dict(
|
88
|
+
# normal=("http://google.com", "google.com"),
|
89
|
+
# ),
|
90
|
+
# checkers=dict(
|
91
|
+
# ovld=ovld,
|
92
|
+
# beartype=beartype,
|
93
|
+
# # typeguard=typechecked,
|
94
|
+
# # strongtyping=match_typing,
|
95
|
+
# ),
|
96
|
+
# )
|
97
|
+
# def urlregexp(url: Regexp[r"^http://.*"]):
|
98
|
+
# return url.split("://")[1]
|
99
|
+
|
100
|
+
|
101
|
+
# @typecheck_test(
|
102
|
+
# cases=dict(
|
103
|
+
# normal=([1, 2, 3], 1),
|
104
|
+
# ),
|
105
|
+
# checkers=dict(
|
106
|
+
# ovld=ovld,
|
107
|
+
# beartype=beartype,
|
108
|
+
# typeguard=typechecked,
|
109
|
+
# strongtyping=match_typing,
|
110
|
+
# ),
|
111
|
+
# )
|
112
|
+
# def firstelem(elements: list[int]):
|
113
|
+
# return elements[0]
|
114
|
+
|
115
|
+
|
116
|
+
# @typecheck_test(
|
117
|
+
# cases=dict(
|
118
|
+
# normal=(123, Point(1, 2), "low", "whatever"),
|
119
|
+
# ),
|
120
|
+
# checkers=dict(
|
121
|
+
# ovld=ovld,
|
122
|
+
# beartype=beartype,
|
123
|
+
# typeguard=typechecked,
|
124
|
+
# strongtyping=match_typing,
|
125
|
+
# ),
|
126
|
+
# )
|
127
|
+
# def misc(
|
128
|
+
# numero: Number, dc: Dataclass, method: Literal["low"] | Literal["high"]
|
129
|
+
# ):
|
130
|
+
# return "whatever"
|
131
|
+
|
132
|
+
|
133
|
+
# @typecheck_test(
|
134
|
+
# cases=dict(
|
135
|
+
# normal=(10, 11),
|
136
|
+
# ),
|
137
|
+
# checkers=dict(
|
138
|
+
# ovld=ovld,
|
139
|
+
# beartype=beartype,
|
140
|
+
# # typeguard=typechecked,
|
141
|
+
# # strongtyping=match_typing,
|
142
|
+
# ),
|
143
|
+
# )
|
144
|
+
# def positive(x: Dependent[int, lambda x: x > 0]):
|
145
|
+
# return x + 1
|
146
|
+
|
147
|
+
|
148
|
+
# @typecheck_test(
|
149
|
+
# cases=dict(
|
150
|
+
# normal=((1, Point(2, 3), "blah"), ("blah", Point(2, 3), 1)),
|
151
|
+
# ),
|
152
|
+
# checkers=dict(
|
153
|
+
# ovld=ovld,
|
154
|
+
# beartype=beartype,
|
155
|
+
# typeguard=typechecked,
|
156
|
+
# strongtyping=match_typing,
|
157
|
+
# ),
|
158
|
+
# )
|
159
|
+
# def triple(xyz: tuple[Number, Dataclass, Collection]):
|
160
|
+
# return tuple(reversed(xyz))
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
## Unique features
|
5
5
|
|
6
|
-
Current as of
|
6
|
+
Current as of October 2024: I have investigated and benchmarked six other multiple/single dispatch libraries. Performance-wise, `ovld` is faster than all of them, ranging from 1.5x to 100x less overhead. Feature-wise, `ovld` is among the most featureful. Some features I could not find elsewhere:
|
7
7
|
|
8
8
|
* Support for [keyword arguments](usage.md#keyword-arguments).
|
9
9
|
* [Variants](usage.md#variants), especially working with recursion.
|
@@ -27,10 +27,11 @@ Current as of September 2024: I have investigated and benchmarked six other mult
|
|
27
27
|
Applicable libraries were tested on the following problems:
|
28
28
|
|
29
29
|
* [trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py): Basic single dispatch test with a bunch of types.
|
30
|
-
* [add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py): Recursively add lists and dictionaries element-wise.
|
31
30
|
* [multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py): Recursively multiply lists and dictionaries element-wise by a number, but using a class. This tests dispatch on methods.
|
31
|
+
* [add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py): Recursively add lists and dictionaries element-wise.
|
32
32
|
* [ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py): Simple transform on a Python AST.
|
33
33
|
* [calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py): Calculator implementation. Dispatches using `op: Literal[<opname>]`.
|
34
|
+
* [regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py): Dispatch based on a regular expression (`ovld.dependent.Regexp[<regex>]`).
|
34
35
|
* [fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py): Fibonacci numbers. The base cases are implemented by dispatching on `n: Literal[0]` and `n: Literal[1]`.
|
35
36
|
* [tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py): Dispatching on keyword arguments.
|
36
37
|
|
@@ -39,21 +40,21 @@ Applicable libraries were tested on the following problems:
|
|
39
40
|
|
40
41
|
Time relative to the fastest implementation (1.00) (lower is better). Python version: 3.12.4
|
41
42
|
|
42
|
-
The **custom** column represents custom implementations using isinstance, match, a dispatch dict, etc. They are usually the fastest, but that should not be surprising. ovld's performance ranges from 1.
|
43
|
+
The **custom** column represents custom implementations using isinstance, match, a dispatch dict, etc. They are usually the fastest, but that should not be surprising. ovld's performance ranges from 1.5x faster to 3.3x slower.
|
43
44
|
|
44
|
-
|
|
45
|
+
| Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch/) | [runtype](https://github.com/erezsh/runtype) | [fastcore](https://github.com/fastai/fastcore) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
|
45
46
|
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
46
|
-
|[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.
|
47
|
-
|[
|
48
|
-
|[
|
49
|
-
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.
|
50
|
-
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.
|
51
|
-
|[
|
52
|
-
|[
|
53
|
-
|
47
|
+
|[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|51.93|1.91|
|
48
|
+
|[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|46.74|7.32|
|
49
|
+
|[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|59.31|x|
|
50
|
+
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|28.39|1.66|
|
51
|
+
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|x|
|
52
|
+
|[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|x|
|
53
|
+
|[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|x|
|
54
|
+
|[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|x|
|
54
55
|
|
55
56
|
## Comments
|
56
57
|
|
57
58
|
A big part of ovld's advantage comes from generating custom dispatch methods depending on the set of signatures that were registered. If you can avoid looping over `*args`, you're basically halving your overhead. Regarding dispatch on `Literal`, ovld also generates custom dispatch methods that unroll a series of specific if/else statements, which is the only way you'll ever get spitting distance from a normal implementation.
|
58
59
|
|
59
|
-
I haven't benchmarked the overhead of registering and compiling the methods, nor cache miss resolves, but
|
60
|
+
I haven't benchmarked the overhead of registering and compiling the methods, nor cache miss resolves, but I expect ovld will do pretty badly in that regard. That'll be the next big push, probably.
|
@@ -2,7 +2,7 @@ import json
|
|
2
2
|
from collections import defaultdict
|
3
3
|
from pathlib import Path
|
4
4
|
|
5
|
-
file = Path(".benchmarks/Darwin-CPython-3.12-64bit/
|
5
|
+
file = Path(".benchmarks/Darwin-CPython-3.12-64bit/0019_report.json")
|
6
6
|
data = json.loads(file.read_text())
|
7
7
|
|
8
8
|
|
@@ -35,7 +35,16 @@ columns = [
|
|
35
35
|
"https://docs.python.org/3/library/functools.html#functools.singledispatch",
|
36
36
|
],
|
37
37
|
]
|
38
|
-
bench_names = [
|
38
|
+
bench_names = [
|
39
|
+
"trivial",
|
40
|
+
"multer",
|
41
|
+
"add",
|
42
|
+
"ast",
|
43
|
+
"calc",
|
44
|
+
"regexp",
|
45
|
+
"fib",
|
46
|
+
"tweaknum",
|
47
|
+
]
|
39
48
|
|
40
49
|
|
41
50
|
template = "https://github.com/breuleux/ovld/tree/master/benchmarks/test_{}.py"
|
@@ -52,6 +61,7 @@ for name in bench_names:
|
|
52
61
|
min(bench["stats"]["median"] for bench in benches)
|
53
62
|
for cat, benches in group.items()
|
54
63
|
# if cat != "custom"
|
64
|
+
if cat != "recurse"
|
55
65
|
)
|
56
66
|
loc = template.format(name)
|
57
67
|
line = [f"[{name}]({loc})"]
|