diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-09-23 18:17:35 +0100 |
---|---|---|
committer | da-woods <dw-git@d-woods.co.uk> | 2022-09-23 19:37:41 +0100 |
commit | 1f74f750fddf202ed2030b5715821e9205f7f5c1 (patch) | |
tree | d1554ddd2a95ed2ef557e25af9d8f314a4d8a779 | |
parent | c7cc5d962545ab59367243dccd307a4f074100f1 (diff) | |
download | cython-1f74f750fddf202ed2030b5715821e9205f7f5c1.tar.gz |
Unpack methods in non-dict mapping
Minor optimization
-rw-r--r-- | Cython/Utility/MatchCase.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/Cython/Utility/MatchCase.c b/Cython/Utility/MatchCase.c index f76950335..1b92d4312 100644 --- a/Cython/Utility/MatchCase.c +++ b/Cython/Utility/MatchCase.c @@ -564,6 +564,9 @@ static int __Pyx__MatchCase_Mapping_ExtractNonDict(void *__pyx_refnanny, PyObjec PyObject *dummy=NULL, *get=NULL; Py_ssize_t i; int result = 0; +#if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL + PyObject *get_method = NULL, *get_self = NULL; +#endif dummy = PyObject_CallObject((PyObject *)&PyBaseObject_Type, NULL); if (!dummy) { @@ -574,16 +577,32 @@ static int __Pyx__MatchCase_Mapping_ExtractNonDict(void *__pyx_refnanny, PyObjec result = -1; goto end; } +#if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL + if (likely(PyMethod_Check(get))) { + // both of these are borrowed + get_method = PyMethod_GET_FUNCTION(get); + get_self = PyMethod_GET_SELF(get); + } +#endif for (i=0; i<nKeys; ++i) { PyObject **subject; PyObject *value = NULL; PyObject *key = keys[i]; - // TODO - there's an optimization here (although it deviates from the strict definition of pattern matching). + // TODO - there's an optimization here (although it deviates from the strict definition of pattern matching). // If we don't need the values then we can call PyObject_Contains instead of "get". If we don't need *any* // of the values then we can skip initialization "get" and "dummy" - value = __Pyx_PyObject_Call2Args(get, key, dummy); +#if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL + if (likely(get_method)) { + PyObject *args[] = { get_self, key, dummy }; + value = _PyObject_Vectorcall(get_method, args, 3, NULL); + } + else +#endif + { + value = __Pyx_PyObject_Call2Args(get, key, dummy); + } if (!value) { result = -1; goto end; @@ -685,4 +704,3 @@ static PyObject* __Pyx_MatchCase_DoubleStarCapture{{tag}}(PyObject *mapping, PyO } return dict_out; } - |