Skip to content

Commit 1f7df35

Browse files
committed
Remove the CACHE_HASH and INTERN_STRINGS preprocessor symbols.
1 parent 8358405 commit 1f7df35

File tree

6 files changed

+19
-102
lines changed

6 files changed

+19
-102
lines changed

Include/stringobject.h

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,18 @@ variant that assumes a zero-terminated string. Note that none of the
2424
functions should be applied to nil objects.
2525
*/
2626

27-
/* Two speedup hacks. Caching the hash saves recalculation of a
28-
string's hash value. Interning strings (which requires hash
29-
caching) tries to ensure that only one string object with a given
30-
value exists, so equality tests are one pointer comparison.
31-
Together, these can speed the interpreter up by as much as 20%.
32-
Each costs the size of a long or pointer per string object. In
33-
addition, interned strings live until the end of times. If you are
34-
concerned about memory footprint, simply comment the #define out
35-
here (and rebuild everything!). */
36-
#define CACHE_HASH
37-
#ifdef CACHE_HASH
38-
#define INTERN_STRINGS
39-
#endif
27+
/* Caching the hash (ob_shash) saves recalculation of a string's hash value.
28+
Interning strings (ob_sinterned) tries to ensure that only one string
29+
object with a given value exists, so equality tests can be one pointer
30+
comparison. This is generally restricted to strings that "look like"
31+
Python identifiers, although the intern() builtin can be used to force
32+
interning of any string.
33+
Together, these sped the interpreter by up to 20%. */
4034

4135
typedef struct {
4236
PyObject_VAR_HEAD
43-
#ifdef CACHE_HASH
4437
long ob_shash;
45-
#endif
46-
#ifdef INTERN_STRINGS
4738
PyObject *ob_sinterned;
48-
#endif
4939
char ob_sval[1];
5040
} PyStringObject;
5141

@@ -70,15 +60,9 @@ extern DL_IMPORT(PyObject *) PyString_Format(PyObject *, PyObject *);
7060
extern DL_IMPORT(PyObject *) _PyString_FormatLong(PyObject*, int, int,
7161
int, char**, int*);
7262

73-
#ifdef INTERN_STRINGS
7463
extern DL_IMPORT(void) PyString_InternInPlace(PyObject **);
7564
extern DL_IMPORT(PyObject *) PyString_InternFromString(const char *);
7665
extern DL_IMPORT(void) _Py_ReleaseInternedStrings(void);
77-
#else
78-
#define PyString_InternInPlace(p)
79-
#define PyString_InternFromString(cp) PyString_FromString(cp)
80-
#define _Py_ReleaseInternedStrings()
81-
#endif
8266

8367
/* Macro, trading safety for speed */
8468
#define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ Tools/Demos
8989

9090
Build
9191

92+
- References to the CACHE_HASH and INTERN_STRINGS preprocessor symbols
93+
were eliminated. They were always defined, and the internal features
94+
they enabled stopped being experimental long ago.
95+
9296
C API
9397

9498
- Objects allocated using the new PyMalloc_New and PyMalloc_NewVar

Objects/bufferobject.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ typedef struct {
1010
void *b_ptr;
1111
int b_size;
1212
int b_readonly;
13-
#ifdef CACHE_HASH
1413
long b_hash;
15-
#endif
1614
} PyBufferObject;
1715

1816

@@ -36,9 +34,7 @@ _PyBuffer_FromMemory(PyObject *base, void *ptr, int size, int readonly)
3634
b->b_ptr = ptr;
3735
b->b_size = size;
3836
b->b_readonly = readonly;
39-
#ifdef CACHE_HASH
4037
b->b_hash = -1;
41-
#endif
4238

4339
return (PyObject *) b;
4440
}
@@ -152,9 +148,7 @@ PyBuffer_New(int size)
152148
b->b_ptr = (void *)(b + 1);
153149
b->b_size = size;
154150
b->b_readonly = 0;
155-
#ifdef CACHE_HASH
156151
b->b_hash = -1;
157-
#endif
158152

159153
return o;
160154
}
@@ -211,10 +205,8 @@ buffer_hash(PyBufferObject *self)
211205
register unsigned char *p;
212206
register long x;
213207

214-
#ifdef CACHE_HASH
215208
if ( self->b_hash != -1 )
216209
return self->b_hash;
217-
#endif
218210

219211
if ( !self->b_readonly )
220212
{
@@ -231,9 +223,7 @@ buffer_hash(PyBufferObject *self)
231223
x ^= self->b_size;
232224
if (x == -1)
233225
x = -2;
234-
#ifdef CACHE_HASH
235226
self->b_hash = x;
236-
#endif
237227
return x;
238228
}
239229

Objects/dictobject.c

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,8 @@ PyDict_GetItem(PyObject *op, PyObject *key)
480480
if (!PyDict_Check(op)) {
481481
return NULL;
482482
}
483-
#ifdef CACHE_HASH
484483
if (!PyString_CheckExact(key) ||
485484
(hash = ((PyStringObject *) key)->ob_shash) == -1)
486-
#endif
487485
{
488486
hash = PyObject_Hash(key);
489487
if (hash == -1) {
@@ -512,24 +510,18 @@ PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
512510
return -1;
513511
}
514512
mp = (dictobject *)op;
515-
#ifdef CACHE_HASH
516513
if (PyString_CheckExact(key)) {
517-
#ifdef INTERN_STRINGS
518514
if (((PyStringObject *)key)->ob_sinterned != NULL) {
519515
key = ((PyStringObject *)key)->ob_sinterned;
520516
hash = ((PyStringObject *)key)->ob_shash;
521517
}
522-
else
523-
#endif
524-
{
518+
else {
525519
hash = ((PyStringObject *)key)->ob_shash;
526520
if (hash == -1)
527521
hash = PyObject_Hash(key);
528522
}
529523
}
530-
else
531-
#endif
532-
{
524+
else {
533525
hash = PyObject_Hash(key);
534526
if (hash == -1)
535527
return -1;
@@ -564,11 +556,8 @@ PyDict_DelItem(PyObject *op, PyObject *key)
564556
PyErr_BadInternalCall();
565557
return -1;
566558
}
567-
#ifdef CACHE_HASH
568559
if (!PyString_CheckExact(key) ||
569-
(hash = ((PyStringObject *) key)->ob_shash) == -1)
570-
#endif
571-
{
560+
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
572561
hash = PyObject_Hash(key);
573562
if (hash == -1)
574563
return -1;
@@ -844,11 +833,8 @@ dict_subscript(dictobject *mp, register PyObject *key)
844833
PyObject *v;
845834
long hash;
846835
assert(mp->ma_table != NULL);
847-
#ifdef CACHE_HASH
848836
if (!PyString_CheckExact(key) ||
849-
(hash = ((PyStringObject *) key)->ob_shash) == -1)
850-
#endif
851-
{
837+
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
852838
hash = PyObject_Hash(key);
853839
if (hash == -1)
854840
return NULL;
@@ -1436,11 +1422,8 @@ dict_has_key(register dictobject *mp, PyObject *key)
14361422
{
14371423
long hash;
14381424
register long ok;
1439-
#ifdef CACHE_HASH
14401425
if (!PyString_CheckExact(key) ||
1441-
(hash = ((PyStringObject *) key)->ob_shash) == -1)
1442-
#endif
1443-
{
1426+
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
14441427
hash = PyObject_Hash(key);
14451428
if (hash == -1)
14461429
return NULL;
@@ -1460,11 +1443,8 @@ dict_get(register dictobject *mp, PyObject *args)
14601443
if (!PyArg_ParseTuple(args, "O|O:get", &key, &failobj))
14611444
return NULL;
14621445

1463-
#ifdef CACHE_HASH
14641446
if (!PyString_CheckExact(key) ||
1465-
(hash = ((PyStringObject *) key)->ob_shash) == -1)
1466-
#endif
1467-
{
1447+
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
14681448
hash = PyObject_Hash(key);
14691449
if (hash == -1)
14701450
return NULL;
@@ -1489,11 +1469,8 @@ dict_setdefault(register dictobject *mp, PyObject *args)
14891469
if (!PyArg_ParseTuple(args, "O|O:setdefault", &key, &failobj))
14901470
return NULL;
14911471

1492-
#ifdef CACHE_HASH
14931472
if (!PyString_CheckExact(key) ||
1494-
(hash = ((PyStringObject *) key)->ob_shash) == -1)
1495-
#endif
1496-
{
1473+
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
14971474
hash = PyObject_Hash(key);
14981475
if (hash == -1)
14991476
return NULL;
@@ -1725,11 +1702,8 @@ dict_contains(dictobject *mp, PyObject *key)
17251702
{
17261703
long hash;
17271704

1728-
#ifdef CACHE_HASH
17291705
if (!PyString_CheckExact(key) ||
1730-
(hash = ((PyStringObject *) key)->ob_shash) == -1)
1731-
#endif
1732-
{
1706+
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
17331707
hash = PyObject_Hash(key);
17341708
if (hash == -1)
17351709
return -1;

Objects/stringobject.c

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,8 @@ PyString_FromStringAndSize(const char *str, int size)
7272
if (op == NULL)
7373
return PyErr_NoMemory();
7474
PyObject_INIT_VAR(op, &PyString_Type, size);
75-
#ifdef CACHE_HASH
7675
op->ob_shash = -1;
77-
#endif
78-
#ifdef INTERN_STRINGS
7976
op->ob_sinterned = NULL;
80-
#endif
8177
if (str != NULL)
8278
memcpy(op->ob_sval, str, size);
8379
op->ob_sval[size] = '\0';
@@ -135,12 +131,8 @@ PyString_FromString(const char *str)
135131
if (op == NULL)
136132
return PyErr_NoMemory();
137133
PyObject_INIT_VAR(op, &PyString_Type, size);
138-
#ifdef CACHE_HASH
139134
op->ob_shash = -1;
140-
#endif
141-
#ifdef INTERN_STRINGS
142135
op->ob_sinterned = NULL;
143-
#endif
144136
memcpy(op->ob_sval, str, size+1);
145137
#ifndef DONT_SHARE_SHORT_STRINGS
146138
if (size == 0) {
@@ -737,12 +729,8 @@ string_concat(register PyStringObject *a, register PyObject *bb)
737729
if (op == NULL)
738730
return PyErr_NoMemory();
739731
PyObject_INIT_VAR(op, &PyString_Type, size);
740-
#ifdef CACHE_HASH
741732
op->ob_shash = -1;
742-
#endif
743-
#ifdef INTERN_STRINGS
744733
op->ob_sinterned = NULL;
745-
#endif
746734
memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
747735
memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
748736
op->ob_sval[size] = '\0';
@@ -784,12 +772,8 @@ string_repeat(register PyStringObject *a, register int n)
784772
if (op == NULL)
785773
return PyErr_NoMemory();
786774
PyObject_INIT_VAR(op, &PyString_Type, size);
787-
#ifdef CACHE_HASH
788775
op->ob_shash = -1;
789-
#endif
790-
#ifdef INTERN_STRINGS
791776
op->ob_sinterned = NULL;
792-
#endif
793777
for (i = 0; i < size; i += a->ob_size)
794778
memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
795779
op->ob_sval[size] = '\0';
@@ -945,15 +929,11 @@ string_hash(PyStringObject *a)
945929
register unsigned char *p;
946930
register long x;
947931

948-
#ifdef CACHE_HASH
949932
if (a->ob_shash != -1)
950933
return a->ob_shash;
951-
#ifdef INTERN_STRINGS
952934
if (a->ob_sinterned != NULL)
953935
return (a->ob_shash =
954936
((PyStringObject *)(a->ob_sinterned))->ob_shash);
955-
#endif
956-
#endif
957937
len = a->ob_size;
958938
p = (unsigned char *) a->ob_sval;
959939
x = *p << 7;
@@ -962,9 +942,7 @@ string_hash(PyStringObject *a)
962942
x ^= a->ob_size;
963943
if (x == -1)
964944
x = -2;
965-
#ifdef CACHE_HASH
966945
a->ob_shash = x;
967-
#endif
968946
return x;
969947
}
970948

@@ -2730,14 +2708,10 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
27302708
pnew = type->tp_alloc(type, n);
27312709
if (pnew != NULL) {
27322710
memcpy(PyString_AS_STRING(pnew), PyString_AS_STRING(tmp), n+1);
2733-
#ifdef CACHE_HASH
27342711
((PyStringObject *)pnew)->ob_shash =
27352712
((PyStringObject *)tmp)->ob_shash;
2736-
#endif
2737-
#ifdef INTERN_STRINGS
27382713
((PyStringObject *)pnew)->ob_sinterned =
27392714
((PyStringObject *)tmp)->ob_sinterned;
2740-
#endif
27412715
}
27422716
Py_DECREF(tmp);
27432717
return pnew;
@@ -3579,7 +3553,6 @@ PyString_Format(PyObject *format, PyObject *args)
35793553
}
35803554

35813555

3582-
#ifdef INTERN_STRINGS
35833556

35843557
/* This dictionary will leak at PyString_Fini() time. That's acceptable
35853558
* because PyString_Fini() specifically frees interned strings that are
@@ -3656,8 +3629,6 @@ PyString_InternFromString(const char *cp)
36563629
return s;
36573630
}
36583631

3659-
#endif
3660-
36613632
void
36623633
PyString_Fini(void)
36633634
{
@@ -3670,7 +3641,6 @@ PyString_Fini(void)
36703641
Py_XDECREF(nullstring);
36713642
nullstring = NULL;
36723643
#endif
3673-
#ifdef INTERN_STRINGS
36743644
if (interned) {
36753645
int pos, changed;
36763646
PyObject *key, *value;
@@ -3685,10 +3655,8 @@ PyString_Fini(void)
36853655
}
36863656
} while (changed);
36873657
}
3688-
#endif
36893658
}
36903659

3691-
#ifdef INTERN_STRINGS
36923660
void _Py_ReleaseInternedStrings(void)
36933661
{
36943662
if (interned) {
@@ -3698,4 +3666,3 @@ void _Py_ReleaseInternedStrings(void)
36983666
interned = NULL;
36993667
}
37003668
}
3701-
#endif /* INTERN_STRINGS */

Python/import.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,6 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
978978
if (strlen(buf) != len)
979979
continue; /* v contains '\0' */
980980
#ifdef macintosh
981-
#ifdef INTERN_STRINGS
982981
/*
983982
** Speedup: each sys.path item is interned, and
984983
** FindResourceModule remembers which items refer to
@@ -987,7 +986,6 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen,
987986
*/
988987
PyString_InternInPlace(&PyList_GET_ITEM(path, i));
989988
v = PyList_GET_ITEM(path, i);
990-
#endif
991989
if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) {
992990
static struct filedescr resfiledescr =
993991
{"", "", PY_RESOURCE};

0 commit comments

Comments
 (0)