[Python-checkins] python/dist/src/Objects listobject.c,2.106,2.107 iterobject.c,1.9,1.10

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Fri, 31 May 2002 14:37:05 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv8943

Modified Files:
	listobject.c iterobject.c 
Log Message:
SF 560736.  Optimize list iteration by filling the tp_iter slot.


Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.106
retrieving revision 2.107
diff -C2 -d -r2.106 -r2.107
*** listobject.c	22 May 2002 23:19:16 -0000	2.106
--- listobject.c	31 May 2002 21:37:01 -0000	2.107
***************
*** 1683,1686 ****
--- 1683,1688 ----
  "list(sequence) -> new list initialized from sequence's items";
  
+ staticforward PyObject * list_iter(PyObject *seq);
+ 
  PyTypeObject PyList_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
***************
*** 1711,1715 ****
  	list_richcompare,			/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
! 	0,					/* tp_iter */
  	0,					/* tp_iternext */
  	list_methods,				/* tp_methods */
--- 1713,1717 ----
  	list_richcompare,			/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
! 	list_iter,				/* tp_iter */
  	0,					/* tp_iternext */
  	list_methods,				/* tp_methods */
***************
*** 1812,1813 ****
--- 1814,1930 ----
  	/* NOTE: This is *not* the standard list_type struct! */
  };
+ 
+ 
+ /*********************** List Iterator **************************/
+ 
+ typedef struct {
+         PyObject_HEAD
+         long      it_index;
+         PyObject *it_seq;
+ } listiterobject;
+ 
+ PyTypeObject PyListIter_Type;
+ 
+ PyObject *
+ list_iter(PyObject *seq)
+ {
+         listiterobject *it;
+ 
+         if (!PyList_Check(seq)) {
+                 PyErr_BadInternalCall();
+                 return NULL;
+         }
+         it = PyObject_GC_New(listiterobject, &PyListIter_Type);
+         if (it == NULL)
+                 return NULL;
+         it->it_index = 0;
+         Py_INCREF(seq);
+         it->it_seq = seq;
+         _PyObject_GC_TRACK(it);
+         return (PyObject *)it;
+ }
+ 
+ static void
+ listiter_dealloc(listiterobject *it)
+ {
+         _PyObject_GC_UNTRACK(it);
+         Py_DECREF(it->it_seq);
+         PyObject_GC_Del(it);
+ }
+ 
+ static int
+ listiter_traverse(listiterobject *it, visitproc visit, void *arg)
+ {
+         return visit(it->it_seq, arg);
+ }
+ 
+ 
+ static PyObject *
+ listiter_getiter(PyObject *it)
+ {
+         Py_INCREF(it);
+         return it;
+ }
+ 
+ static PyObject *
+ listiter_next(PyObject *it)
+ {
+         PyObject *seq;
+         PyObject *item;
+ 
+         assert(PyList_Check(it));
+         seq = ((listiterobject *)it)->it_seq;
+ 
+         if (((listiterobject *)it)->it_index < PyList_GET_SIZE(seq)) {
+ 		item = ((PyListObject *)(seq))->ob_item[((listiterobject *)it)->it_index++];
+                 Py_INCREF(item);
+                 return item;
+         }
+         return NULL;
+ }
+ 
+ static PyMethodDef listiter_methods[] = {
+         {"next",        (PyCFunction)listiter_next,     METH_NOARGS,
+          "it.next() -- get the next value, or raise StopIteration"},
+         {NULL,          NULL}           /* sentinel */
+ };
+ 
+ PyTypeObject PyListIter_Type = {
+         PyObject_HEAD_INIT(&PyType_Type)
+         0,                                      /* ob_size */
+         "listiterator",                         /* tp_name */
+         sizeof(listiterobject),                 /* tp_basicsize */
+         0,                                      /* tp_itemsize */
+         /* methods */
+         (destructor)listiter_dealloc,           /* tp_dealloc */
+         0,                                      /* tp_print */
+         0,                                      /* tp_getattr */
+         0,                                      /* tp_setattr */
+         0,                                      /* tp_compare */
+         0,                                      /* tp_repr */
+         0,                                      /* tp_as_number */
+         0,                                      /* tp_as_sequence */
+         0,                                      /* tp_as_mapping */
+         0,                                      /* tp_hash */
+         0,                                      /* tp_call */
+         0,                                      /* tp_str */
+         PyObject_GenericGetAttr,                /* tp_getattro */
+         0,                                      /* tp_setattro */
+         0,                                      /* tp_as_buffer */
+         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+         0,                                      /* tp_doc */
+         (traverseproc)listiter_traverse,        /* tp_traverse */
+         0,                                      /* tp_clear */
+         0,                                      /* tp_richcompare */
+         0,                                      /* tp_weaklistoffset */
+         (getiterfunc)listiter_getiter,          /* tp_iter */
+         (iternextfunc)listiter_next,            /* tp_iternext */
+         listiter_methods,			/* tp_methods */
+         0,                                      /* tp_members */
+         0,                                      /* tp_getset */
+         0,                                      /* tp_base */
+         0,                                      /* tp_dict */
+         0,                                      /* tp_descr_get */
+         0,                                      /* tp_descr_set */
+ };
+ 

Index: iterobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** iterobject.c	8 May 2002 08:44:21 -0000	1.9
--- iterobject.c	31 May 2002 21:37:01 -0000	1.10
***************
*** 69,91 ****
  	seq = it->it_seq;
  
- 	if (PyList_CheckExact(seq)) {
- 		PyObject *item;
- 		if (it->it_index >= PyList_GET_SIZE(seq)) {
- 			return NULL;
- 		}
- 		item = PyList_GET_ITEM(seq, it->it_index);
- 		it->it_index++;
- 		Py_INCREF(item);
- 		return item;
- 	}
  	if (PyTuple_CheckExact(seq)) {
! 		PyObject *item;
! 		if (it->it_index >= PyTuple_GET_SIZE(seq)) {
! 			return NULL;
  		}
! 		item = PyTuple_GET_ITEM(seq, it->it_index);
! 		it->it_index++;
! 		Py_INCREF(item);
! 		return item;
  	}
  	else {
--- 69,81 ----
  	seq = it->it_seq;
  
  	if (PyTuple_CheckExact(seq)) {
! 		if (it->it_index < PyTuple_GET_SIZE(seq)) {
! 			PyObject *item;
! 			item = PyTuple_GET_ITEM(seq, it->it_index);
! 			it->it_index++;
! 			Py_INCREF(item);
! 			return item;
  		}
! 		return NULL;
  	}
  	else {