[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.112,2.113
Tim Peters
tim_one@users.sourceforge.net
Thu, 13 Sep 2001 17:25:35 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv10172/python/Objects
Modified Files:
dictobject.c
Log Message:
Changed the dict implementation to take "string shortcuts" only when
keys are true strings -- no subclasses need apply. This may be debatable.
The problem is that a str subclass may very well want to override __eq__
and/or __hash__ (see the new example of case-insensitive strings in
test_descr), but go-fast shortcuts for strings are ubiquitous in our dicts
(and subclass overrides aren't even looked for then). Another go-fast
reason for the change is that PyCheck_StringExact() is a quicker test
than PyCheck_String(), and we make such a test on virtually every access
to every dict.
OTOH, a str subclass may also be perfectly happy using the base str eq
and hash, and this change slows them a lot. But those cases are still
hypothetical, while Python's own reliance on true-string dicts is not.
Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.112
retrieving revision 2.113
diff -C2 -d -r2.112 -r2.113
*** dictobject.c 2001/09/02 18:35:54 2.112
--- dictobject.c 2001/09/14 00:25:33 2.113
***************
*** 299,304 ****
* _PyString_Eq directly.
*
! * This really only becomes meaningful if proper error handling in lookdict()
! * is too expensive.
*/
static dictentry *
--- 299,304 ----
* _PyString_Eq directly.
*
! * This is valuable because the general-case error handling in lookdict() is
! * expensive, and dicts with pure-string keys are very common.
*/
static dictentry *
***************
*** 312,317 ****
register dictentry *ep;
! /* make sure this function doesn't have to handle non-string keys */
! if (!PyString_Check(key)) {
#ifdef SHOW_CONVERSION_COUNTS
++converted;
--- 312,320 ----
register dictentry *ep;
! /* Make sure this function doesn't have to handle non-string keys,
! including subclasses of str; e.g., one reason to subclass
! strings is to override __eq__, and for speed we don't cater to
! that here. */
! if (!PyString_CheckExact(key)) {
#ifdef SHOW_CONVERSION_COUNTS
++converted;
***************
*** 479,483 ****
}
#ifdef CACHE_HASH
! if (!PyString_Check(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
--- 482,486 ----
}
#ifdef CACHE_HASH
! if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
***************
*** 511,515 ****
mp = (dictobject *)op;
#ifdef CACHE_HASH
! if (PyString_Check(key)) {
#ifdef INTERN_STRINGS
if (((PyStringObject *)key)->ob_sinterned != NULL) {
--- 514,518 ----
mp = (dictobject *)op;
#ifdef CACHE_HASH
! if (PyString_CheckExact(key)) {
#ifdef INTERN_STRINGS
if (((PyStringObject *)key)->ob_sinterned != NULL) {
***************
*** 563,567 ****
}
#ifdef CACHE_HASH
! if (!PyString_Check(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
--- 566,570 ----
}
#ifdef CACHE_HASH
! if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
***************
*** 821,825 ****
goto Done;
result = _PyString_Join(s, pieces);
! Py_DECREF(s);
Done:
--- 824,828 ----
goto Done;
result = _PyString_Join(s, pieces);
! Py_DECREF(s);
Done:
***************
*** 843,847 ****
assert(mp->ma_table != NULL);
#ifdef CACHE_HASH
! if (!PyString_Check(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
--- 846,850 ----
assert(mp->ma_table != NULL);
#ifdef CACHE_HASH
! if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
***************
*** 1359,1363 ****
register long ok;
#ifdef CACHE_HASH
! if (!PyString_Check(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
--- 1362,1366 ----
register long ok;
#ifdef CACHE_HASH
! if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
***************
*** 1383,1387 ****
#ifdef CACHE_HASH
! if (!PyString_Check(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
--- 1386,1390 ----
#ifdef CACHE_HASH
! if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
***************
*** 1412,1416 ****
#ifdef CACHE_HASH
! if (!PyString_Check(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
--- 1415,1419 ----
#ifdef CACHE_HASH
! if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
***************
*** 1648,1652 ****
#ifdef CACHE_HASH
! if (!PyString_Check(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
--- 1651,1655 ----
#ifdef CACHE_HASH
! if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif