Remove the CACHE_HASH and INTERN_STRINGS preprocessor symbols.

This commit is contained in:
Tim Peters 2002-03-29 03:29:08 +00:00
parent 835840560b
commit 1f7df3595a
6 changed files with 19 additions and 102 deletions

View File

@ -24,28 +24,18 @@ variant that assumes a zero-terminated string. Note that none of the
functions should be applied to nil objects.
*/
/* Two speedup hacks. Caching the hash saves recalculation of a
string's hash value. Interning strings (which requires hash
caching) tries to ensure that only one string object with a given
value exists, so equality tests are one pointer comparison.
Together, these can speed the interpreter up by as much as 20%.
Each costs the size of a long or pointer per string object. In
addition, interned strings live until the end of times. If you are
concerned about memory footprint, simply comment the #define out
here (and rebuild everything!). */
#define CACHE_HASH
#ifdef CACHE_HASH
#define INTERN_STRINGS
#endif
/* Caching the hash (ob_shash) saves recalculation of a string's hash value.
Interning strings (ob_sinterned) tries to ensure that only one string
object with a given value exists, so equality tests can be one pointer
comparison. This is generally restricted to strings that "look like"
Python identifiers, although the intern() builtin can be used to force
interning of any string.
Together, these sped the interpreter by up to 20%. */
typedef struct {
PyObject_VAR_HEAD
#ifdef CACHE_HASH
long ob_shash;
#endif
#ifdef INTERN_STRINGS
PyObject *ob_sinterned;
#endif
char ob_sval[1];
} PyStringObject;
@ -70,15 +60,9 @@ extern DL_IMPORT(PyObject *) PyString_Format(PyObject *, PyObject *);
extern DL_IMPORT(PyObject *) _PyString_FormatLong(PyObject*, int, int,
int, char**, int*);
#ifdef INTERN_STRINGS
extern DL_IMPORT(void) PyString_InternInPlace(PyObject **);
extern DL_IMPORT(PyObject *) PyString_InternFromString(const char *);
extern DL_IMPORT(void) _Py_ReleaseInternedStrings(void);
#else
#define PyString_InternInPlace(p)
#define PyString_InternFromString(cp) PyString_FromString(cp)
#define _Py_ReleaseInternedStrings()
#endif
/* Macro, trading safety for speed */
#define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval)

View File

@ -89,6 +89,10 @@ Tools/Demos
Build
- References to the CACHE_HASH and INTERN_STRINGS preprocessor symbols
were eliminated. They were always defined, and the internal features
they enabled stopped being experimental long ago.
C API
- Objects allocated using the new PyMalloc_New and PyMalloc_NewVar

View File

@ -10,9 +10,7 @@ typedef struct {
void *b_ptr;
int b_size;
int b_readonly;
#ifdef CACHE_HASH
long b_hash;
#endif
} PyBufferObject;
@ -36,9 +34,7 @@ _PyBuffer_FromMemory(PyObject *base, void *ptr, int size, int readonly)
b->b_ptr = ptr;
b->b_size = size;
b->b_readonly = readonly;
#ifdef CACHE_HASH
b->b_hash = -1;
#endif
return (PyObject *) b;
}
@ -152,9 +148,7 @@ PyBuffer_New(int size)
b->b_ptr = (void *)(b + 1);
b->b_size = size;
b->b_readonly = 0;
#ifdef CACHE_HASH
b->b_hash = -1;
#endif
return o;
}
@ -211,10 +205,8 @@ buffer_hash(PyBufferObject *self)
register unsigned char *p;
register long x;
#ifdef CACHE_HASH
if ( self->b_hash != -1 )
return self->b_hash;
#endif
if ( !self->b_readonly )
{
@ -231,9 +223,7 @@ buffer_hash(PyBufferObject *self)
x ^= self->b_size;
if (x == -1)
x = -2;
#ifdef CACHE_HASH
self->b_hash = x;
#endif
return x;
}

View File

@ -480,10 +480,8 @@ PyDict_GetItem(PyObject *op, PyObject *key)
if (!PyDict_Check(op)) {
return NULL;
}
#ifdef CACHE_HASH
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
{
hash = PyObject_Hash(key);
if (hash == -1) {
@ -512,24 +510,18 @@ PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
return -1;
}
mp = (dictobject *)op;
#ifdef CACHE_HASH
if (PyString_CheckExact(key)) {
#ifdef INTERN_STRINGS
if (((PyStringObject *)key)->ob_sinterned != NULL) {
key = ((PyStringObject *)key)->ob_sinterned;
hash = ((PyStringObject *)key)->ob_shash;
}
else
#endif
{
else {
hash = ((PyStringObject *)key)->ob_shash;
if (hash == -1)
hash = PyObject_Hash(key);
}
}
else
#endif
{
else {
hash = PyObject_Hash(key);
if (hash == -1)
return -1;
@ -564,11 +556,8 @@ PyDict_DelItem(PyObject *op, PyObject *key)
PyErr_BadInternalCall();
return -1;
}
#ifdef CACHE_HASH
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
{
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return -1;
@ -844,11 +833,8 @@ dict_subscript(dictobject *mp, register PyObject *key)
PyObject *v;
long hash;
assert(mp->ma_table != NULL);
#ifdef CACHE_HASH
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
{
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return NULL;
@ -1436,11 +1422,8 @@ dict_has_key(register dictobject *mp, PyObject *key)
{
long hash;
register long ok;
#ifdef CACHE_HASH
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
{
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return NULL;
@ -1460,11 +1443,8 @@ dict_get(register dictobject *mp, PyObject *args)
if (!PyArg_ParseTuple(args, "O|O:get", &key, &failobj))
return NULL;
#ifdef CACHE_HASH
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
{
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return NULL;
@ -1489,11 +1469,8 @@ dict_setdefault(register dictobject *mp, PyObject *args)
if (!PyArg_ParseTuple(args, "O|O:setdefault", &key, &failobj))
return NULL;
#ifdef CACHE_HASH
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
{
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return NULL;
@ -1725,11 +1702,8 @@ dict_contains(dictobject *mp, PyObject *key)
{
long hash;
#ifdef CACHE_HASH
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
{
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return -1;

View File

@ -72,12 +72,8 @@ PyString_FromStringAndSize(const char *str, int size)
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
#ifdef INTERN_STRINGS
op->ob_sinterned = NULL;
#endif
if (str != NULL)
memcpy(op->ob_sval, str, size);
op->ob_sval[size] = '\0';
@ -135,12 +131,8 @@ PyString_FromString(const char *str)
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
#ifdef INTERN_STRINGS
op->ob_sinterned = NULL;
#endif
memcpy(op->ob_sval, str, size+1);
#ifndef DONT_SHARE_SHORT_STRINGS
if (size == 0) {
@ -737,12 +729,8 @@ string_concat(register PyStringObject *a, register PyObject *bb)
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
#ifdef INTERN_STRINGS
op->ob_sinterned = NULL;
#endif
memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
op->ob_sval[size] = '\0';
@ -784,12 +772,8 @@ string_repeat(register PyStringObject *a, register int n)
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
#ifdef INTERN_STRINGS
op->ob_sinterned = NULL;
#endif
for (i = 0; i < size; i += a->ob_size)
memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
op->ob_sval[size] = '\0';
@ -945,15 +929,11 @@ string_hash(PyStringObject *a)
register unsigned char *p;
register long x;
#ifdef CACHE_HASH
if (a->ob_shash != -1)
return a->ob_shash;
#ifdef INTERN_STRINGS
if (a->ob_sinterned != NULL)
return (a->ob_shash =
((PyStringObject *)(a->ob_sinterned))->ob_shash);
#endif
#endif
len = a->ob_size;
p = (unsigned char *) a->ob_sval;
x = *p << 7;
@ -962,9 +942,7 @@ string_hash(PyStringObject *a)
x ^= a->ob_size;
if (x == -1)
x = -2;
#ifdef CACHE_HASH
a->ob_shash = x;
#endif
return x;
}
@ -2730,14 +2708,10 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
pnew = type->tp_alloc(type, n);
if (pnew != NULL) {
memcpy(PyString_AS_STRING(pnew), PyString_AS_STRING(tmp), n+1);
#ifdef CACHE_HASH
((PyStringObject *)pnew)->ob_shash =
((PyStringObject *)tmp)->ob_shash;
#endif
#ifdef INTERN_STRINGS
((PyStringObject *)pnew)->ob_sinterned =
((PyStringObject *)tmp)->ob_sinterned;
#endif
}
Py_DECREF(tmp);
return pnew;
@ -3579,7 +3553,6 @@ PyString_Format(PyObject *format, PyObject *args)
}
#ifdef INTERN_STRINGS
/* This dictionary will leak at PyString_Fini() time. That's acceptable
* because PyString_Fini() specifically frees interned strings that are
@ -3656,8 +3629,6 @@ PyString_InternFromString(const char *cp)
return s;
}
#endif
void
PyString_Fini(void)
{
@ -3670,7 +3641,6 @@ PyString_Fini(void)
Py_XDECREF(nullstring);
nullstring = NULL;
#endif
#ifdef INTERN_STRINGS
if (interned) {
int pos, changed;
PyObject *key, *value;
@ -3685,10 +3655,8 @@ PyString_Fini(void)
}
} while (changed);
}
#endif
}
#ifdef INTERN_STRINGS
void _Py_ReleaseInternedStrings(void)
{
if (interned) {
@ -3698,4 +3666,3 @@ void _Py_ReleaseInternedStrings(void)
interned = NULL;
}
}
#endif /* INTERN_STRINGS */

View File

@ -978,7 +978,6 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
if (strlen(buf) != len)
continue; /* v contains '\0' */
#ifdef macintosh
#ifdef INTERN_STRINGS
/*
** Speedup: each sys.path item is interned, and
** FindResourceModule remembers which items refer to
@ -987,7 +986,6 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
*/
PyString_InternInPlace(&PyList_GET_ITEM(path, i));
v = PyList_GET_ITEM(path, i);
#endif
if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) {
static struct filedescr resfiledescr =
{"", "", PY_RESOURCE};