summaryrefslogtreecommitdiffstats
path: root/Python/getargs.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2013-02-17 00:04:57 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2013-02-17 00:04:57 (GMT)
commit7056cb286715e5d5768ef06100d1e5b77c1df6cc (patch)
treea33fba288dcc47f54e3d5e03909a8b8848f7e8ab /Python/getargs.c
parente924ddb23e4276b601cdc13d2988e501123f85fb (diff)
downloadcpython-7056cb286715e5d5768ef06100d1e5b77c1df6cc.zip
cpython-7056cb286715e5d5768ef06100d1e5b77c1df6cc.tar.gz
cpython-7056cb286715e5d5768ef06100d1e5b77c1df6cc.tar.bz2
Issue #17170: speed up PyArg_ParseTuple[AndKeywords] a bit.
Diffstat (limited to 'Python/getargs.c')
-rw-r--r--Python/getargs.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/Python/getargs.c b/Python/getargs.c
index ae931b9..08faeb4 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -46,10 +46,12 @@ typedef struct {
} freelistentry_t;
typedef struct {
- int first_available;
freelistentry_t *entries;
+ int first_available;
+ int entries_malloced;
} freelist_t;
+#define STATIC_FREELIST_ENTRIES 8
/* Forward */
static int vgetargs1(PyObject *, const char *, va_list *, int);
@@ -187,7 +189,8 @@ cleanreturn(int retval, freelist_t *freelist)
freelist->entries[index].item);
}
}
- PyMem_FREE(freelist->entries);
+ if (freelist->entries_malloced)
+ PyMem_FREE(freelist->entries);
return retval;
}
@@ -197,6 +200,8 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
{
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 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
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 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
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 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
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 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
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 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
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 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
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) {