[Python-checkins] cpython: Issue #17170: speed up PyArg_ParseTuple[AndKeywords] a bit.

antoine.pitrou python-checkins at python.org
Sun Feb 17 01:09:17 CET 2013


http://hg.python.org/cpython/rev/4e985a96a612
changeset:   82233:4e985a96a612
parent:      82229:aa17a0dab86a
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Sun Feb 17 01:04:57 2013 +0100
summary:
  Issue #17170: speed up PyArg_ParseTuple[AndKeywords] a bit.

files:
  Python/getargs.c |  57 ++++++++++++++++++++---------------
  1 files changed, 32 insertions(+), 25 deletions(-)


diff --git a/Python/getargs.c b/Python/getargs.c
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -46,10 +46,12 @@
 } freelistentry_t;
 
 typedef struct {
+  freelistentry_t *entries;
   int first_available;
-  freelistentry_t *entries;
+  int entries_malloced;
 } freelist_t;
 
+#define STATIC_FREELIST_ENTRIES 8
 
 /* Forward */
 static int vgetargs1(PyObject *, const char *, va_list *, int);
@@ -187,7 +189,8 @@
                                               freelist->entries[index].item);
       }
     }
-    PyMem_FREE(freelist->entries);
+    if (freelist->entries_malloced)
+        PyMem_FREE(freelist->entries);
     return retval;
 }
 
@@ -197,6 +200,8 @@
 {
     char msgbuf[256];
     int levels[32];
+    freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
+    freelist_t freelist = {static_entries, 0, 0};
     const char *fname = NULL;
     const char *message = NULL;
     int min = -1;
@@ -206,7 +211,6 @@
     const char *formatsave = format;
     Py_ssize_t i, len;
     char *msg;
-    freelist_t freelist = {0, NULL};
     int compat = flags & FLAG_COMPAT;
 
     assert(compat || (args != (PyObject*)NULL));
@@ -240,15 +244,15 @@
             message = format;
             endfmt = 1;
             break;
+        case '|':
+            if (level == 0)
+                min = max;
+            break;
         default:
             if (level == 0) {
-                if (c == 'O')
-                    max++;
-                else if (Py_ISALPHA(Py_CHARMASK(c))) {
+                if (Py_ISALPHA(Py_CHARMASK(c)))
                     if (c != 'e') /* skip encoded */
                         max++;
-                } else if (c == '|')
-                    min = max;
             }
             break;
         }
@@ -262,10 +266,13 @@
 
     format = formatsave;
 
-    freelist.entries = PyMem_NEW(freelistentry_t, max);
-    if (freelist.entries == NULL) {
-        PyErr_NoMemory();
-        return 0;
+    if (max > STATIC_FREELIST_ENTRIES) {
+        freelist.entries = PyMem_NEW(freelistentry_t, max);
+        if (freelist.entries == NULL) {
+            PyErr_NoMemory();
+            return 0;
+        }
+        freelist.entries_malloced = 1;
     }
 
     if (compat) {
@@ -1421,7 +1428,8 @@
     int max = INT_MAX;
     int i, len, nargs, nkeywords;
     PyObject *current_arg;
-    freelist_t freelist = {0, NULL};
+    freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
+    freelist_t freelist = {static_entries, 0, 0};
 
     assert(args != NULL && PyTuple_Check(args));
     assert(keywords == NULL || PyDict_Check(keywords));
@@ -1445,10 +1453,13 @@
     for (len=0; kwlist[len]; len++)
         continue;
 
-    freelist.entries = PyMem_NEW(freelistentry_t, len);
-    if (freelist.entries == NULL) {
-        PyErr_NoMemory();
-        return 0;
+    if (len > STATIC_FREELIST_ENTRIES) {
+        freelist.entries = PyMem_NEW(freelistentry_t, len);
+        if (freelist.entries == NULL) {
+            PyErr_NoMemory();
+            return 0;
+        }
+        freelist.entries_malloced = 1;
     }
 
     nargs = PyTuple_GET_SIZE(args);
@@ -1574,20 +1585,16 @@
         Py_ssize_t pos = 0;
         while (PyDict_Next(keywords, &pos, &key, &value)) {
             int match = 0;
-            char *ks;
             if (!PyUnicode_Check(key)) {
                 PyErr_SetString(PyExc_TypeError,
                                 "keywords must be strings");
                 return cleanreturn(0, &freelist);
             }
             /* check that _PyUnicode_AsString() result is not NULL */
-            ks = _PyUnicode_AsString(key);
-            if (ks != NULL) {
-                for (i = 0; i < len; i++) {
-                    if (!strcmp(ks, kwlist[i])) {
-                        match = 1;
-                        break;
-                    }
+            for (i = 0; i < len; i++) {
+                if (!PyUnicode_CompareWithASCIIString(key, kwlist[i])) {
+                    match = 1;
+                    break;
                 }
             }
             if (!match) {

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list