[Python-checkins] CVS: python/dist/src/Python compile.c,2.105,2.106
Guido van Rossum
python-dev@python.org
Fri, 28 Apr 2000 12:42:28 -0400 (EDT)
Update of /projects/cvsroot/python/dist/src/Python
In directory eric:/projects/python/develop/guido/src/Python
Modified Files:
compile.c
Log Message:
Charles G Waldman:
Follow a suggestion in an /*XXX*/ comment [in com_add()] to speed up
compilation by using supplemental dictionaries to keep track of names
and constants, eliminating quadratic behavior. With this patch in
place, the time to import a 5000-line file with lots of constants [at
the global level] is reduced from 20 seconds to under 3 on my system.
Index: compile.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Python/compile.c,v
retrieving revision 2.105
retrieving revision 2.106
diff -C2 -r2.105 -r2.106
*** compile.c 2000/04/13 14:10:44 2.105
--- compile.c 2000/04/28 16:42:25 2.106
***************
*** 302,306 ****
--- 302,308 ----
PyObject *c_code; /* string */
PyObject *c_consts; /* list of objects */
+ PyObject *c_const_dict; /* inverse of c_consts */
PyObject *c_names; /* list of strings (names) */
+ PyObject *c_name_dict; /* inverse of c_names */
PyObject *c_globals; /* dictionary (value=None) */
PyObject *c_locals; /* dictionary (value=localID) */
***************
*** 404,408 ****
static void com_addfwref Py_PROTO((struct compiling *, int, int *));
static void com_backpatch Py_PROTO((struct compiling *, int));
! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *));
static int com_addconst Py_PROTO((struct compiling *, PyObject *));
static int com_addname Py_PROTO((struct compiling *, PyObject *));
--- 406,410 ----
static void com_addfwref Py_PROTO((struct compiling *, int, int *));
static void com_backpatch Py_PROTO((struct compiling *, int));
! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *, PyObject *));
static int com_addconst Py_PROTO((struct compiling *, PyObject *));
static int com_addname Py_PROTO((struct compiling *, PyObject *));
***************
*** 422,441 ****
char *filename;
{
if ((c->c_code = PyString_FromStringAndSize((char *)NULL,
1000)) == NULL)
! goto fail_3;
if ((c->c_consts = PyList_New(0)) == NULL)
! goto fail_2;
if ((c->c_names = PyList_New(0)) == NULL)
! goto fail_1;
if ((c->c_globals = PyDict_New()) == NULL)
! goto fail_0;
if ((c->c_locals = PyDict_New()) == NULL)
! goto fail_00;
if ((c->c_varnames = PyList_New(0)) == NULL)
! goto fail_000;
if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL,
1000)) == NULL)
! goto fail_0000;
c->c_nlocals = 0;
c->c_argcount = 0;
--- 424,448 ----
char *filename;
{
+ memset((void *)c, '\0', sizeof(struct compiling));
if ((c->c_code = PyString_FromStringAndSize((char *)NULL,
1000)) == NULL)
! goto fail;
if ((c->c_consts = PyList_New(0)) == NULL)
! goto fail;
! if ((c->c_const_dict = PyDict_New()) == NULL)
! goto fail;
if ((c->c_names = PyList_New(0)) == NULL)
! goto fail;
! if ((c->c_name_dict = PyDict_New()) == NULL)
! goto fail;
if ((c->c_globals = PyDict_New()) == NULL)
! goto fail;
if ((c->c_locals = PyDict_New()) == NULL)
! goto fail;
if ((c->c_varnames = PyList_New(0)) == NULL)
! goto fail;
if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL,
1000)) == NULL)
! goto fail;
c->c_nlocals = 0;
c->c_argcount = 0;
***************
*** 459,475 ****
return 1;
! fail_0000:
! Py_DECREF(c->c_varnames);
! fail_000:
! Py_DECREF(c->c_locals);
! fail_00:
! Py_DECREF(c->c_globals);
! fail_0:
! Py_DECREF(c->c_names);
! fail_1:
! Py_DECREF(c->c_consts);
! fail_2:
! Py_DECREF(c->c_code);
! fail_3:
return 0;
}
--- 466,471 ----
return 1;
! fail:
! com_free(c);
return 0;
}
***************
*** 481,485 ****
--- 477,483 ----
Py_XDECREF(c->c_code);
Py_XDECREF(c->c_consts);
+ Py_XDECREF(c->c_const_dict);
Py_XDECREF(c->c_names);
+ Py_XDECREF(c->c_name_dict);
Py_XDECREF(c->c_globals);
Py_XDECREF(c->c_locals);
***************
*** 666,687 ****
static int
! com_add(c, list, v)
struct compiling *c;
PyObject *list;
PyObject *v;
{
! int n = PyList_Size(list);
! int i;
! /* XXX This is quadratic in the number of names per compilation unit.
! XXX Should use a dictionary. */
! for (i = n; --i >= 0; ) {
! PyObject *w = PyList_GetItem(list, i);
! if (v->ob_type == w->ob_type && PyObject_Compare(v, w) == 0)
! return i;
! }
! /* Check for error from PyObject_Compare */
! if (PyErr_Occurred() || PyList_Append(list, v) != 0)
! c->c_errors++;
return n;
}
--- 664,700 ----
static int
! com_add(c, list, dict, v)
struct compiling *c;
PyObject *list;
+ PyObject *dict;
PyObject *v;
{
! PyObject *w, *t, *np=NULL;
! long n;
!
! t = Py_BuildValue("(OO)", v, v->ob_type);
! if (t == NULL)
! goto fail;
! w = PyDict_GetItem(dict, t);
! if (w != NULL) {
! n = PyInt_AsLong(w);
! } else {
! n = PyList_Size(list);
! np = PyInt_FromLong(n);
! if (np == NULL)
! goto fail;
! if (PyList_Append(list, v) != 0)
! goto fail;
! if (PyDict_SetItem(dict, t, np) != 0)
! goto fail;
! Py_DECREF(np);
! }
! Py_DECREF(t);
return n;
+ fail:
+ Py_XDECREF(np);
+ Py_XDECREF(t);
+ c->c_errors++;
+ return 0;
}
***************
*** 691,695 ****
PyObject *v;
{
! return com_add(c, c->c_consts, v);
}
--- 704,708 ----
PyObject *v;
{
! return com_add(c, c->c_consts, c->c_const_dict, v);
}
***************
*** 699,703 ****
PyObject *v;
{
! return com_add(c, c->c_names, v);
}
--- 712,716 ----
PyObject *v;
{
! return com_add(c, c->c_names, c->c_name_dict, v);
}