Issue 26098: [WIP] PEP 510: Specialize functions with guards (original) (raw)

Created on 2016-01-13 12:52 by vstinner, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
specialize.patch vstinner,2016-01-13 12:52 review
specialize-2.patch vstinner,2016-01-13 14:12 review
specialize-3.patch vstinner,2016-01-19 12:51 review
specialize-4.patch vstinner,2016-01-23 13:02 review
specialize-5.patch vstinner,2016-01-27 10:54 review
specialize-6.patch vstinner,2016-02-03 00:01 review
specialize-7.patch vstinner,2016-02-05 10:25 review
specialize-8.patch vstinner,2016-02-05 10:29 review
Pull Requests
URL Status Linked Edit
PR 2354 closed vstinner,2017-06-23 11:56
Messages (13)
msg258141 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-01-13 12:52
Attached patch implements the PEP 510 "Specialize functions with guards". Changes on the C API are described in the PEP: https://www.python.org/dev/peps/pep-0510/#changes Additions of the patch: * Add func_specialize() and func_get_specialized() to _testcapi * Add _testcapi.PyGuard: Python wrapper to the Guard C API * Add Lib/test/test_pep510.py
msg258143 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-01-13 14:12
Patch version 2 fixes some bugs and add more tests. More notes about the patch: * RuntimeError is raised if guard check() result is greater than 2 * RuntimeError is raised if guard init() result is greater than 1 * (hum, maybe 'res < 0' check must be replaced with 'res == -1', but I'm not sure that that it's worth it.) * If PyFunction_Specialize() is called with a code object or a Python code, it creates a new code object and copies the code name and first line number in the new code object to ease debugging TODO: keywords are currently not supported in PyGuard.__call__().
msg258147 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-01-13 15:24
An unit test is needed on pickle serialization to ensure that the specialize code and guards are ignored.
msg258591 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-01-19 12:51
Patch version 3: * guards are now tracked by the garbage collector. That's a very important requirements to not change the Python semantics at exit, when a guard keeps a strong reference to the global namespace: https://mail.python.org/pipermail/python-dev/2016-January/142792.html * add more tests: call specialize() with invalid types, set __code__
msg258868 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-01-23 13:02
Patch version 4: * Keywords are now supported everywhere and tested by unit tests * Inline specode_check() into PyFunction_GetSpecializedCode()
msg259012 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-01-27 10:54
Patch version 5: implement PyFunction_RemoveSpecialized() and PyFunction_RemoveAllSpecialized() functions (with unit tests!). I'm not sure that PyFunction_RemoveSpecialized() must return 0 (success) if the removed specialized code doesn't exist (invalid index).
msg259068 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-01-27 22:01
FIXME: sys.getsizecode(func) doesn't include specialized code and guards.
msg259447 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-02-03 00:01
Patch version 6: I inlined PyFunction_GetSpecializedCode() into fast_function() of Python/ceval.c. It reduces *a little bit* the overhead of the patch when specialization is not used, but it also avoids to expose this function. I don't think that it's worth to expose PyFunction_GetSpecializedCode(): it was only used in ceval.c. For example, I don't use it for unit tests. I prefer to write tests calling the function and checking the results (see test_pep510.py). *Raw* overhead of specialized-6.patch on calling "def f(): pass": 1.7 nanoseconds. I computed the overhead using timeit: ./python -m timeit -s 'def f(): pass' 'f()' * Original: 71.7 ns * specialize-6.patch: 73.4 ns (+1.7 ns, +2.4%) * specialize-5.patch: 74.3 ns (+2.6 ns, +3.6%) I will run perf.py to see the overhead on a macro benchmark.
msg259450 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-02-03 00:53
Results of the "The Grand Unified Python Benchmark Suite" on specialize-6.patch. I'm skeptical, I don't understand how my patch can make a benchmark faster :-) The result of regex_v8 is bad :-/ $ python3 -u perf.py --rigorous ../default/python.orig ../default/python (...) Report on Linux smithers 4.3.3-300.fc23.x86_64 #1 SMP Tue Jan 5 23:31:01 UTC 2016 x86_64 x86_64 Total CPU cores: 8 ### chameleon_v2 ### Min: 5.558607 -> 5.831682: 1.05x slower Avg: 5.613403 -> 5.902949: 1.05x slower Significant (t=-27.95) Stddev: 0.06994 -> 0.07640: 1.0924x larger ### django_v3 ### Min: 0.582356 -> 0.573327: 1.02x faster Avg: 0.604402 -> 0.582197: 1.04x faster Significant (t=3.43) Stddev: 0.05618 -> 0.03215: 1.7474x smaller ### regex_v8 ### Min: 0.043784 -> 0.049854: 1.14x slower Avg: 0.044270 -> 0.050521: 1.14x slower Significant (t=-19.87) Stddev: 0.00200 -> 0.00243: 1.2105x larger The following not significant results are hidden, use -v to show them: 2to3, fastpickle, fastunpickle, json_dump_v2, json_load, nbody, tornado_http.
msg259653 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-02-05 10:25
Patch version 7: * Fix a random crash related to _testcapi.PyGuard: implement tp_traverse on PyFuncGuard and "inherit" tp_traverse on PyGuard * Fix a typo Include/funcobject.h * (rebase the patch)
msg259654 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-02-05 10:29
Oh, I missed comments on the code review. Fixed on patch version 8.
msg296703 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-06-23 11:59
Recently, some people asked me for an update for my FAT Python project. So I rebased this change I wrote 1 year 1/2 and adapted it for the new code base: * I renamed test_pep510.py to test_func_specialize.py * I removed the useless PyFunction_Check() macro * I changed the guard check prototype to use the new FASTCALL calling convention: (PyObject **args, Py_ssize_t nargs, PyObject *kwnames: tuple) * I patched _PyFunction_FastCallDict() *and* PyFunction_FastCallKeywords() to check guards and call specified code if guards succeeded The PEP 510 is not accepted, so the implementation is still a work-in-progress (WIP) and must not be merged.
msg304525 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-10-17 20:12
I rejected my own PEP 510, so I reject this issue as well. https://mail.python.org/pipermail/python-dev/2017-October/149901.html
History
Date User Action Args
2022-04-11 14:58:26 admin set github: 70286
2017-10-17 20:12:30 vstinner set status: open -> closedresolution: rejectedmessages: + stage: resolved
2017-06-28 01:12:18 vstinner set title: PEP 510: Specialize functions with guards -> [WIP] PEP 510: Specialize functions with guards
2017-06-23 11:59:33 vstinner set messages: +
2017-06-23 11:56:24 vstinner set pull_requests: + <pull%5Frequest2400>
2017-05-29 15:25:18 Jim Fasarakis-Hilliard set nosy: + Jim Fasarakis-Hilliard
2016-02-05 10:29:42 vstinner set files: + specialize-8.patchmessages: +
2016-02-05 10:25:19 vstinner set files: + specialize-7.patchmessages: +
2016-02-03 00:53:37 vstinner set messages: +
2016-02-03 00:01:50 vstinner set files: + specialize-6.patchmessages: +
2016-01-27 22:01:58 vstinner set messages: +
2016-01-27 10:54:44 vstinner set files: + specialize-5.patchmessages: +
2016-01-23 13:02:15 vstinner set files: + specialize-4.patchmessages: +
2016-01-19 12:51:09 vstinner set files: + specialize-3.patchmessages: +
2016-01-13 15:24:08 vstinner set messages: +
2016-01-13 14:12:39 vstinner set files: + specialize-2.patchmessages: +
2016-01-13 12:52:48 vstinner create