[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.80,2.81

Guido van Rossum gvanrossum@users.sourceforge.net
Tue, 01 May 2001 05:10:23 -0700


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

Modified Files:
	dictobject.c 
Log Message:
Add experimental iterkeys(), itervalues(), iteritems() to dict
objects.

Tests show that iteritems() is 5-10% faster than iterating over the
dict and extracting the value with dict[key].


Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.80
retrieving revision 2.81
diff -C2 -r2.80 -r2.81
*** dictobject.c	2001/04/23 14:08:49	2.80
--- dictobject.c	2001/05/01 12:10:21	2.81
***************
*** 1232,1235 ****
--- 1232,1290 ----
  
  
+ staticforward PyObject *dictiter_new(dictobject *, binaryfunc);
+ 
+ static PyObject *
+ select_key(PyObject *key, PyObject *value)
+ {
+ 	Py_INCREF(key);
+ 	return key;
+ }
+ 
+ static PyObject *
+ select_value(PyObject *key, PyObject *value)
+ {
+ 	Py_INCREF(value);
+ 	return value;
+ }
+ 
+ static PyObject *
+ select_item(PyObject *key, PyObject *value)
+ {
+ 	PyObject *res = PyTuple_New(2);
+ 
+ 	if (res != NULL) {
+ 		Py_INCREF(key);
+ 		Py_INCREF(value);
+ 		PyTuple_SET_ITEM(res, 0, key);
+ 		PyTuple_SET_ITEM(res, 1, value);
+ 	}
+ 	return res;
+ }
+ 
+ static PyObject *
+ dict_iterkeys(dictobject *dict, PyObject *args)
+ {
+ 	if (!PyArg_ParseTuple(args, ""))
+ 		return NULL;
+ 	return dictiter_new(dict, select_key);
+ }
+ 
+ static PyObject *
+ dict_itervalues(dictobject *dict, PyObject *args)
+ {
+ 	if (!PyArg_ParseTuple(args, ""))
+ 		return NULL;
+ 	return dictiter_new(dict, select_value);
+ }
+ 
+ static PyObject *
+ dict_iteritems(dictobject *dict, PyObject *args)
+ {
+ 	if (!PyArg_ParseTuple(args, ""))
+ 		return NULL;
+ 	return dictiter_new(dict, select_item);
+ }
+ 
+ 
  static char has_key__doc__[] =
  "D.has_key(k) -> 1 if D has a key k, else 0";
***************
*** 1263,1266 ****
--- 1318,1330 ----
  "D.copy() -> a shallow copy of D";
  
+ static char iterkeys__doc__[] =
+ "D.iterkeys() -> an iterator over the keys of D";
+ 
+ static char itervalues__doc__[] =
+ "D.itervalues() -> an iterator over the values of D";
+ 
+ static char iteritems__doc__[] =
+ "D.iteritems() -> an iterator over the (key, value) items of D";
+ 
  static PyMethodDef mapp_methods[] = {
  	{"has_key",	(PyCFunction)dict_has_key,      METH_VARARGS,
***************
*** 1284,1287 ****
--- 1348,1357 ----
  	{"copy",	(PyCFunction)dict_copy,		METH_OLDARGS,
  	 copy__doc__},
+ 	{"iterkeys",	(PyCFunction)dict_iterkeys,	METH_VARARGS,
+ 	 iterkeys__doc__},
+ 	{"itervalues",	(PyCFunction)dict_itervalues,	METH_VARARGS,
+ 	 itervalues__doc__},
+ 	{"iteritems",	(PyCFunction)dict_iteritems,	METH_VARARGS,
+ 	 iteritems__doc__},
  	{NULL,		NULL}	/* sentinel */
  };
***************
*** 1325,1329 ****
  };
  
! staticforward PyObject *dictiter_new(dictobject *);
  
  PyTypeObject PyDict_Type = {
--- 1395,1403 ----
  };
  
! static PyObject *
! dict_iter(dictobject *dict)
! {
! 	return dictiter_new(dict, select_key);
! }
  
  PyTypeObject PyDict_Type = {
***************
*** 1354,1358 ****
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
! 	(getiterfunc)dictiter_new,		/* tp_iter */
  	0,					/* tp_iternext */
  };
--- 1428,1432 ----
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
! 	(getiterfunc)dict_iter,			/* tp_iter */
  	0,					/* tp_iternext */
  };
***************
*** 1408,1415 ****
  	int di_size;
  	int di_pos;
  } dictiterobject;
  
  static PyObject *
! dictiter_new(dictobject *dict)
  {
  	dictiterobject *di;
--- 1482,1490 ----
  	int di_size;
  	int di_pos;
+ 	binaryfunc di_select;
  } dictiterobject;
  
  static PyObject *
! dictiter_new(dictobject *dict, binaryfunc select)
  {
  	dictiterobject *di;
***************
*** 1421,1424 ****
--- 1496,1500 ----
  	di->di_size = dict->ma_size;
  	di->di_pos = 0;
+ 	di->di_select = select;
  	return (PyObject *)di;
  }
***************
*** 1434,1438 ****
  dictiter_next(dictiterobject *di, PyObject *args)
  {
! 	PyObject *key;
  
  	if (di->di_size != di->di_dict->ma_size) {
--- 1510,1514 ----
  dictiter_next(dictiterobject *di, PyObject *args)
  {
! 	PyObject *key, *value;
  
  	if (di->di_size != di->di_dict->ma_size) {
***************
*** 1441,1447 ****
  		return NULL;
  	}
! 	if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, NULL)) {
! 		Py_INCREF(key);
! 		return key;
  	}
  	PyErr_SetObject(PyExc_StopIteration, Py_None);
--- 1517,1522 ----
  		return NULL;
  	}
! 	if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value)) {
! 		return (*di->di_select)(key, value);
  	}
  	PyErr_SetObject(PyExc_StopIteration, Py_None);
***************
*** 1470,1474 ****
  static PyObject *dictiter_iternext(dictiterobject *di)
  {
! 	PyObject *key;
  
  	if (di->di_size != di->di_dict->ma_size) {
--- 1545,1549 ----
  static PyObject *dictiter_iternext(dictiterobject *di)
  {
! 	PyObject *key, *value;
  
  	if (di->di_size != di->di_dict->ma_size) {
***************
*** 1477,1483 ****
  		return NULL;
  	}
! 	if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, NULL)) {
! 		Py_INCREF(key);
! 		return key;
  	}
  	return NULL;
--- 1552,1557 ----
  		return NULL;
  	}
! 	if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value)) {
! 		return (*di->di_select)(key, value);
  	}
  	return NULL;