[Python-checkins] CVS: python/dist/src/Objects classobject.c,2.84,2.85
Jeremy Hylton
python-dev@python.org
2000年4月26日 16:39:23 -0400
Update of /projects/cvsroot/python/dist/src/Objects
In directory goon.cnri.reston.va.us:/home/jhylton/python/linux/Python-1.6a2/Objects
Modified Files:
classobject.c
Log Message:
potentially useless optimization
The previous checkin (2.84) added a PyErr_Format call that made the
cost of raising an AttributeError much more expensive. In general
this doesn't matter, except that checks for __init__ and
__del__ methods, where exceptions are caught and cleared in C, also
got much more expensive.
The fix is to split instance_getattr1 into two calls:
instance_getattr2 checks the instance and the class for the attribute
and returns it or returns NULL on error. It does not raise an
exception.
instance_getattr1 does rexec checks, then calls instance_getattr2. It
raises an exception if instance_getattr2 returns NULL.
PyInstance_New and instance_dealloc now call instance_getattr2
directly.
Index: classobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/classobject.c,v
retrieving revision 2.84
retrieving revision 2.85
diff -C2 -r2.84 -r2.85
*** classobject.c 2000年04月10日 13:03:19 2.84
--- classobject.c 2000年04月26日 20:39:20 2.85
***************
*** 39,42 ****
--- 39,43 ----
Py_PROTO((PyClassObject *, PyObject *, PyClassObject **));
static PyObject *instance_getattr1 Py_PROTO((PyInstanceObject *, PyObject *));
+ static PyObject *instance_getattr2 Py_PROTO((PyInstanceObject *, PyObject *));
static PyObject *getattrstr, *setattrstr, *delattrstr;
***************
*** 457,463 ****
if (initstr == NULL)
initstr = PyString_InternFromString("__init__");
! init = instance_getattr1(inst, initstr);
if (init == NULL) {
- PyErr_Clear();
if ((arg != NULL && (!PyTuple_Check(arg) ||
PyTuple_Size(arg) != 0))
--- 458,463 ----
if (initstr == NULL)
initstr = PyString_InternFromString("__init__");
! init = instance_getattr2(inst, initstr);
if (init == NULL) {
if ((arg != NULL && (!PyTuple_Check(arg) ||
PyTuple_Size(arg) != 0))
***************
*** 516,520 ****
if (delstr == NULL)
delstr = PyString_InternFromString("__del__");
! if ((del = instance_getattr1(inst, delstr)) != NULL) {
PyObject *res = PyEval_CallObject(del, (PyObject *)NULL);
if (res == NULL) {
--- 516,520 ----
if (delstr == NULL)
delstr = PyString_InternFromString("__del__");
! if ((del = instance_getattr2(inst, delstr)) != NULL) {
PyObject *res = PyEval_CallObject(del, (PyObject *)NULL);
if (res == NULL) {
***************
*** 572,576 ****
register PyObject *v;
register char *sname = PyString_AsString(name);
- PyClassObject *class;
if (sname[0] == '_' && sname[1] == '_') {
if (strcmp(sname, "__dict__") == 0) {
--- 572,575 ----
***************
*** 588,602 ****
}
}
class = NULL;
v = PyDict_GetItem(inst->in_dict, name);
if (v == NULL) {
v = class_lookup(inst->in_class, name, &class);
! if (v == NULL) {
! PyErr_Format(PyExc_AttributeError,
! "'%.50s' instance has no attribute '%.400s'",
! PyString_AsString(inst->in_class->cl_name),
! sname);
! return NULL;
! }
}
Py_INCREF(v);
--- 587,611 ----
}
}
+ v = instance_getattr2(inst, name);
+ if (v == NULL) {
+ PyErr_Format(PyExc_AttributeError,"'%.50s' instance has no attribute '%.400s'",
+ PyString_AS_STRING(inst->in_class->cl_name), sname);
+ }
+ return v;
+ }
+
+ static PyObject *
+ instance_getattr2(inst, name)
+ register PyInstanceObject *inst;
+ PyObject *name;
+ {
+ register PyObject *v;
+ PyClassObject *class;
class = NULL;
v = PyDict_GetItem(inst->in_dict, name);
if (v == NULL) {
v = class_lookup(inst->in_class, name, &class);
! if (v == NULL)
! return v;
}
Py_INCREF(v);