summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2022-09-23 18:17:35 +0100
committerda-woods <dw-git@d-woods.co.uk>2022-09-23 19:37:41 +0100
commit1f74f750fddf202ed2030b5715821e9205f7f5c1 (patch)
treed1554ddd2a95ed2ef557e25af9d8f314a4d8a779
parentc7cc5d962545ab59367243dccd307a4f074100f1 (diff)
downloadcython-1f74f750fddf202ed2030b5715821e9205f7f5c1.tar.gz
Unpack methods in non-dict mapping
Minor optimization
-rw-r--r--Cython/Utility/MatchCase.c24
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;
}
-