[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);

AltStyle によって変換されたページ (->オリジナル) /