mirror of https://github.com/python/cpython
Remove the CACHE_HASH and INTERN_STRINGS preprocessor symbols.
This commit is contained in:
parent
835840560b
commit
1f7df3595a
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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};
|
||||
|
|
Loading…
Reference in New Issue