mirror of
https://github.com/python/cpython.git
synced 2025-09-04 07:51:13 +00:00
Issue #17170: speed up PyArg_ParseTuple[AndKeywords] a bit.
This commit is contained in:
parent
e924ddb23e
commit
7056cb2867
1 changed files with 32 additions and 25 deletions
|
@ -46,10 +46,12 @@ typedef struct {
|
||||||
} freelistentry_t;
|
} freelistentry_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int first_available;
|
|
||||||
freelistentry_t *entries;
|
freelistentry_t *entries;
|
||||||
|
int first_available;
|
||||||
|
int entries_malloced;
|
||||||
} freelist_t;
|
} freelist_t;
|
||||||
|
|
||||||
|
#define STATIC_FREELIST_ENTRIES 8
|
||||||
|
|
||||||
/* Forward */
|
/* Forward */
|
||||||
static int vgetargs1(PyObject *, const char *, va_list *, int);
|
static int vgetargs1(PyObject *, const char *, va_list *, int);
|
||||||
|
@ -187,7 +189,8 @@ cleanreturn(int retval, freelist_t *freelist)
|
||||||
freelist->entries[index].item);
|
freelist->entries[index].item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PyMem_FREE(freelist->entries);
|
if (freelist->entries_malloced)
|
||||||
|
PyMem_FREE(freelist->entries);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +200,8 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
||||||
{
|
{
|
||||||
char msgbuf[256];
|
char msgbuf[256];
|
||||||
int levels[32];
|
int levels[32];
|
||||||
|
freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
|
||||||
|
freelist_t freelist = {static_entries, 0, 0};
|
||||||
const char *fname = NULL;
|
const char *fname = NULL;
|
||||||
const char *message = NULL;
|
const char *message = NULL;
|
||||||
int min = -1;
|
int min = -1;
|
||||||
|
@ -206,7 +211,6 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
||||||
const char *formatsave = format;
|
const char *formatsave = format;
|
||||||
Py_ssize_t i, len;
|
Py_ssize_t i, len;
|
||||||
char *msg;
|
char *msg;
|
||||||
freelist_t freelist = {0, NULL};
|
|
||||||
int compat = flags & FLAG_COMPAT;
|
int compat = flags & FLAG_COMPAT;
|
||||||
|
|
||||||
assert(compat || (args != (PyObject*)NULL));
|
assert(compat || (args != (PyObject*)NULL));
|
||||||
|
@ -240,15 +244,15 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
||||||
message = format;
|
message = format;
|
||||||
endfmt = 1;
|
endfmt = 1;
|
||||||
break;
|
break;
|
||||||
|
case '|':
|
||||||
|
if (level == 0)
|
||||||
|
min = max;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
if (c == 'O')
|
if (Py_ISALPHA(Py_CHARMASK(c)))
|
||||||
max++;
|
|
||||||
else if (Py_ISALPHA(Py_CHARMASK(c))) {
|
|
||||||
if (c != 'e') /* skip encoded */
|
if (c != 'e') /* skip encoded */
|
||||||
max++;
|
max++;
|
||||||
} else if (c == '|')
|
|
||||||
min = max;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -262,10 +266,13 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
||||||
|
|
||||||
format = formatsave;
|
format = formatsave;
|
||||||
|
|
||||||
freelist.entries = PyMem_NEW(freelistentry_t, max);
|
if (max > STATIC_FREELIST_ENTRIES) {
|
||||||
if (freelist.entries == NULL) {
|
freelist.entries = PyMem_NEW(freelistentry_t, max);
|
||||||
PyErr_NoMemory();
|
if (freelist.entries == NULL) {
|
||||||
return 0;
|
PyErr_NoMemory();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
freelist.entries_malloced = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compat) {
|
if (compat) {
|
||||||
|
@ -1421,7 +1428,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
|
||||||
int max = INT_MAX;
|
int max = INT_MAX;
|
||||||
int i, len, nargs, nkeywords;
|
int i, len, nargs, nkeywords;
|
||||||
PyObject *current_arg;
|
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(args != NULL && PyTuple_Check(args));
|
||||||
assert(keywords == NULL || PyDict_Check(keywords));
|
assert(keywords == NULL || PyDict_Check(keywords));
|
||||||
|
@ -1445,10 +1453,13 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
|
||||||
for (len=0; kwlist[len]; len++)
|
for (len=0; kwlist[len]; len++)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
freelist.entries = PyMem_NEW(freelistentry_t, len);
|
if (len > STATIC_FREELIST_ENTRIES) {
|
||||||
if (freelist.entries == NULL) {
|
freelist.entries = PyMem_NEW(freelistentry_t, len);
|
||||||
PyErr_NoMemory();
|
if (freelist.entries == NULL) {
|
||||||
return 0;
|
PyErr_NoMemory();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
freelist.entries_malloced = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nargs = PyTuple_GET_SIZE(args);
|
nargs = PyTuple_GET_SIZE(args);
|
||||||
|
@ -1574,20 +1585,16 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
|
||||||
Py_ssize_t pos = 0;
|
Py_ssize_t pos = 0;
|
||||||
while (PyDict_Next(keywords, &pos, &key, &value)) {
|
while (PyDict_Next(keywords, &pos, &key, &value)) {
|
||||||
int match = 0;
|
int match = 0;
|
||||||
char *ks;
|
|
||||||
if (!PyUnicode_Check(key)) {
|
if (!PyUnicode_Check(key)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"keywords must be strings");
|
"keywords must be strings");
|
||||||
return cleanreturn(0, &freelist);
|
return cleanreturn(0, &freelist);
|
||||||
}
|
}
|
||||||
/* check that _PyUnicode_AsString() result is not NULL */
|
/* check that _PyUnicode_AsString() result is not NULL */
|
||||||
ks = _PyUnicode_AsString(key);
|
for (i = 0; i < len; i++) {
|
||||||
if (ks != NULL) {
|
if (!PyUnicode_CompareWithASCIIString(key, kwlist[i])) {
|
||||||
for (i = 0; i < len; i++) {
|
match = 1;
|
||||||
if (!strcmp(ks, kwlist[i])) {
|
break;
|
||||||
match = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue