| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,28 +24,18 @@ variant that assumes a zero-terminated string. Note that none of the | |||
| 24 | 24 | functions should be applied to nil objects. | |
| 25 | 25 | */ | |
| 26 | 26 | ||
| 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%. */ | ||
| 40 | 34 | ||
| 41 | 35 | typedef struct { | |
| 42 | 36 | PyObject_VAR_HEAD | |
| 43 | - #ifdef CACHE_HASH | ||
| 44 | 37 | long ob_shash; | |
| 45 | - #endif | ||
| 46 | - #ifdef INTERN_STRINGS | ||
| 47 | 38 | PyObject *ob_sinterned; | |
| 48 | - #endif | ||
| 49 | 39 | char ob_sval[1]; | |
| 50 | 40 | } PyStringObject; | |
| 51 | 41 | ||
@@ -70,15 +60,9 @@ extern DL_IMPORT(PyObject *) PyString_Format(PyObject *, PyObject *); | |||
| 70 | 60 | extern DL_IMPORT(PyObject *) _PyString_FormatLong(PyObject*, int, int, | |
| 71 | 61 | int, char**, int*); | |
| 72 | 62 | ||
| 73 | - #ifdef INTERN_STRINGS | ||
| 74 | 63 | extern DL_IMPORT(void) PyString_InternInPlace(PyObject **); | |
| 75 | 64 | extern DL_IMPORT(PyObject *) PyString_InternFromString(const char *); | |
| 76 | 65 | 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 | ||
| 82 | 66 | ||
| 83 | 67 | /* Macro, trading safety for speed */ | |
| 84 | 68 | #define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -89,6 +89,10 @@ Tools/Demos | |||
| 89 | 89 | ||
| 90 | 90 | Build | |
| 91 | 91 | ||
| 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 | + | ||
| 92 | 96 | C API | |
| 93 | 97 | ||
| 94 | 98 | - Objects allocated using the new PyMalloc_New and PyMalloc_NewVar | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,9 +10,7 @@ typedef struct { | |||
| 10 | 10 | void *b_ptr; | |
| 11 | 11 | int b_size; | |
| 12 | 12 | int b_readonly; | |
| 13 | - #ifdef CACHE_HASH | ||
| 14 | 13 | long b_hash; | |
| 15 | - #endif | ||
| 16 | 14 | } PyBufferObject; | |
| 17 | 15 | ||
| 18 | 16 | ||
@@ -36,9 +34,7 @@ _PyBuffer_FromMemory(PyObject *base, void *ptr, int size, int readonly) | |||
| 36 | 34 | b->b_ptr = ptr; | |
| 37 | 35 | b->b_size = size; | |
| 38 | 36 | b->b_readonly = readonly; | |
| 39 | - #ifdef CACHE_HASH | ||
| 40 | 37 | b->b_hash = -1; | |
| 41 | - #endif | ||
| 42 | 38 | ||
| 43 | 39 | return (PyObject *) b; | |
| 44 | 40 | } | |
@@ -152,9 +148,7 @@ PyBuffer_New(int size) | |||
| 152 | 148 | b->b_ptr = (void *)(b + 1); | |
| 153 | 149 | b->b_size = size; | |
| 154 | 150 | b->b_readonly = 0; | |
| 155 | - #ifdef CACHE_HASH | ||
| 156 | 151 | b->b_hash = -1; | |
| 157 | - #endif | ||
| 158 | 152 | ||
| 159 | 153 | return o; | |
| 160 | 154 | } | |
@@ -211,10 +205,8 @@ buffer_hash(PyBufferObject *self) | |||
| 211 | 205 | register unsigned char *p; | |
| 212 | 206 | register long x; | |
| 213 | 207 | ||
| 214 | - #ifdef CACHE_HASH | ||
| 215 | 208 | if ( self->b_hash != -1 ) | |
| 216 | 209 | return self->b_hash; | |
| 217 | - #endif | ||
| 218 | 210 | ||
| 219 | 211 | if ( !self->b_readonly ) | |
| 220 | 212 | { | |
@@ -231,9 +223,7 @@ buffer_hash(PyBufferObject *self) | |||
| 231 | 223 | x ^= self->b_size; | |
| 232 | 224 | if (x == -1) | |
| 233 | 225 | x = -2; | |
| 234 | - #ifdef CACHE_HASH | ||
| 235 | 226 | self->b_hash = x; | |
| 236 | - #endif | ||
| 237 | 227 | return x; | |
| 238 | 228 | } | |
| 239 | 229 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -480,10 +480,8 @@ PyDict_GetItem(PyObject *op, PyObject *key) | |||
| 480 | 480 | if (!PyDict_Check(op)) { | |
| 481 | 481 | return NULL; | |
| 482 | 482 | } | |
| 483 | - #ifdef CACHE_HASH | ||
| 484 | 483 | if (!PyString_CheckExact(key) || | |
| 485 | 484 | (hash = ((PyStringObject *) key)->ob_shash) == -1) | |
| 486 | - #endif | ||
| 487 | 485 | { | |
| 488 | 486 | hash = PyObject_Hash(key); | |
| 489 | 487 | if (hash == -1) { | |
@@ -512,24 +510,18 @@ PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value) | |||
| 512 | 510 | return -1; | |
| 513 | 511 | } | |
| 514 | 512 | mp = (dictobject *)op; | |
| 515 | - #ifdef CACHE_HASH | ||
| 516 | 513 | if (PyString_CheckExact(key)) { | |
| 517 | - #ifdef INTERN_STRINGS | ||
| 518 | 514 | if (((PyStringObject *)key)->ob_sinterned != NULL) { | |
| 519 | 515 | key = ((PyStringObject *)key)->ob_sinterned; | |
| 520 | 516 | hash = ((PyStringObject *)key)->ob_shash; | |
| 521 | 517 | } | |
| 522 | - else | ||
| 523 | - #endif | ||
| 524 | - { | ||
| 518 | + else { | ||
| 525 | 519 | hash = ((PyStringObject *)key)->ob_shash; | |
| 526 | 520 | if (hash == -1) | |
| 527 | 521 | hash = PyObject_Hash(key); | |
| 528 | 522 | } | |
| 529 | 523 | } | |
| 530 | - else | ||
| 531 | - #endif | ||
| 532 | - { | ||
| 524 | + else { | ||
| 533 | 525 | hash = PyObject_Hash(key); | |
| 534 | 526 | if (hash == -1) | |
| 535 | 527 | return -1; | |
@@ -564,11 +556,8 @@ PyDict_DelItem(PyObject *op, PyObject *key) | |||
| 564 | 556 | PyErr_BadInternalCall(); | |
| 565 | 557 | return -1; | |
| 566 | 558 | } | |
| 567 | - #ifdef CACHE_HASH | ||
| 568 | 559 | if (!PyString_CheckExact(key) || | |
| 569 | - (hash = ((PyStringObject *) key)->ob_shash) == -1) | ||
| 570 | - #endif | ||
| 571 | - { | ||
| 560 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | ||
| 572 | 561 | hash = PyObject_Hash(key); | |
| 573 | 562 | if (hash == -1) | |
| 574 | 563 | return -1; | |
@@ -844,11 +833,8 @@ dict_subscript(dictobject *mp, register PyObject *key) | |||
| 844 | 833 | PyObject *v; | |
| 845 | 834 | long hash; | |
| 846 | 835 | assert(mp->ma_table != NULL); | |
| 847 | - #ifdef CACHE_HASH | ||
| 848 | 836 | if (!PyString_CheckExact(key) || | |
| 849 | - (hash = ((PyStringObject *) key)->ob_shash) == -1) | ||
| 850 | - #endif | ||
| 851 | - { | ||
| 837 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | ||
| 852 | 838 | hash = PyObject_Hash(key); | |
| 853 | 839 | if (hash == -1) | |
| 854 | 840 | return NULL; | |
@@ -1436,11 +1422,8 @@ dict_has_key(register dictobject *mp, PyObject *key) | |||
| 1436 | 1422 | { | |
| 1437 | 1423 | long hash; | |
| 1438 | 1424 | register long ok; | |
| 1439 | - #ifdef CACHE_HASH | ||
| 1440 | 1425 | if (!PyString_CheckExact(key) || | |
| 1441 | - (hash = ((PyStringObject *) key)->ob_shash) == -1) | ||
| 1442 | - #endif | ||
| 1443 | - { | ||
| 1426 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | ||
| 1444 | 1427 | hash = PyObject_Hash(key); | |
| 1445 | 1428 | if (hash == -1) | |
| 1446 | 1429 | return NULL; | |
@@ -1460,11 +1443,8 @@ dict_get(register dictobject *mp, PyObject *args) | |||
| 1460 | 1443 | if (!PyArg_ParseTuple(args, "O|O:get", &key, &failobj)) | |
| 1461 | 1444 | return NULL; | |
| 1462 | 1445 | ||
| 1463 | - #ifdef CACHE_HASH | ||
| 1464 | 1446 | if (!PyString_CheckExact(key) || | |
| 1465 | - (hash = ((PyStringObject *) key)->ob_shash) == -1) | ||
| 1466 | - #endif | ||
| 1467 | - { | ||
| 1447 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | ||
| 1468 | 1448 | hash = PyObject_Hash(key); | |
| 1469 | 1449 | if (hash == -1) | |
| 1470 | 1450 | return NULL; | |
@@ -1489,11 +1469,8 @@ dict_setdefault(register dictobject *mp, PyObject *args) | |||
| 1489 | 1469 | if (!PyArg_ParseTuple(args, "O|O:setdefault", &key, &failobj)) | |
| 1490 | 1470 | return NULL; | |
| 1491 | 1471 | ||
| 1492 | - #ifdef CACHE_HASH | ||
| 1493 | 1472 | if (!PyString_CheckExact(key) || | |
| 1494 | - (hash = ((PyStringObject *) key)->ob_shash) == -1) | ||
| 1495 | - #endif | ||
| 1496 | - { | ||
| 1473 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | ||
| 1497 | 1474 | hash = PyObject_Hash(key); | |
| 1498 | 1475 | if (hash == -1) | |
| 1499 | 1476 | return NULL; | |
@@ -1725,11 +1702,8 @@ dict_contains(dictobject *mp, PyObject *key) | |||
| 1725 | 1702 | { | |
| 1726 | 1703 | long hash; | |
| 1727 | 1704 | ||
| 1728 | - #ifdef CACHE_HASH | ||
| 1729 | 1705 | if (!PyString_CheckExact(key) || | |
| 1730 | - (hash = ((PyStringObject *) key)->ob_shash) == -1) | ||
| 1731 | - #endif | ||
| 1732 | - { | ||
| 1706 | + (hash = ((PyStringObject *) key)->ob_shash) == -1) { | ||
| 1733 | 1707 | hash = PyObject_Hash(key); | |
| 1734 | 1708 | if (hash == -1) | |
| 1735 | 1709 | return -1; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -72,12 +72,8 @@ PyString_FromStringAndSize(const char *str, int size) | |||
| 72 | 72 | if (op == NULL) | |
| 73 | 73 | return PyErr_NoMemory(); | |
| 74 | 74 | PyObject_INIT_VAR(op, &PyString_Type, size); | |
| 75 | - #ifdef CACHE_HASH | ||
| 76 | 75 | op->ob_shash = -1; | |
| 77 | - #endif | ||
| 78 | - #ifdef INTERN_STRINGS | ||
| 79 | 76 | op->ob_sinterned = NULL; | |
| 80 | - #endif | ||
| 81 | 77 | if (str != NULL) | |
| 82 | 78 | memcpy(op->ob_sval, str, size); | |
| 83 | 79 | op->ob_sval[size] = '\0'; | |
@@ -135,12 +131,8 @@ PyString_FromString(const char *str) | |||
| 135 | 131 | if (op == NULL) | |
| 136 | 132 | return PyErr_NoMemory(); | |
| 137 | 133 | PyObject_INIT_VAR(op, &PyString_Type, size); | |
| 138 | - #ifdef CACHE_HASH | ||
| 139 | 134 | op->ob_shash = -1; | |
| 140 | - #endif | ||
| 141 | - #ifdef INTERN_STRINGS | ||
| 142 | 135 | op->ob_sinterned = NULL; | |
| 143 | - #endif | ||
| 144 | 136 | memcpy(op->ob_sval, str, size+1); | |
| 145 | 137 | #ifndef DONT_SHARE_SHORT_STRINGS | |
| 146 | 138 | if (size == 0) { | |
@@ -737,12 +729,8 @@ string_concat(register PyStringObject *a, register PyObject *bb) | |||
| 737 | 729 | if (op == NULL) | |
| 738 | 730 | return PyErr_NoMemory(); | |
| 739 | 731 | PyObject_INIT_VAR(op, &PyString_Type, size); | |
| 740 | - #ifdef CACHE_HASH | ||
| 741 | 732 | op->ob_shash = -1; | |
| 742 | - #endif | ||
| 743 | - #ifdef INTERN_STRINGS | ||
| 744 | 733 | op->ob_sinterned = NULL; | |
| 745 | - #endif | ||
| 746 | 734 | memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); | |
| 747 | 735 | memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); | |
| 748 | 736 | op->ob_sval[size] = '\0'; | |
@@ -784,12 +772,8 @@ string_repeat(register PyStringObject *a, register int n) | |||
| 784 | 772 | if (op == NULL) | |
| 785 | 773 | return PyErr_NoMemory(); | |
| 786 | 774 | PyObject_INIT_VAR(op, &PyString_Type, size); | |
| 787 | - #ifdef CACHE_HASH | ||
| 788 | 775 | op->ob_shash = -1; | |
| 789 | - #endif | ||
| 790 | - #ifdef INTERN_STRINGS | ||
| 791 | 776 | op->ob_sinterned = NULL; | |
| 792 | - #endif | ||
| 793 | 777 | for (i = 0; i < size; i += a->ob_size) | |
| 794 | 778 | memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); | |
| 795 | 779 | op->ob_sval[size] = '\0'; | |
@@ -945,15 +929,11 @@ string_hash(PyStringObject *a) | |||
| 945 | 929 | register unsigned char *p; | |
| 946 | 930 | register long x; | |
| 947 | 931 | ||
| 948 | - #ifdef CACHE_HASH | ||
| 949 | 932 | if (a->ob_shash != -1) | |
| 950 | 933 | return a->ob_shash; | |
| 951 | - #ifdef INTERN_STRINGS | ||
| 952 | 934 | if (a->ob_sinterned != NULL) | |
| 953 | 935 | return (a->ob_shash = | |
| 954 | 936 | ((PyStringObject *)(a->ob_sinterned))->ob_shash); | |
| 955 | - #endif | ||
| 956 | - #endif | ||
| 957 | 937 | len = a->ob_size; | |
| 958 | 938 | p = (unsigned char *) a->ob_sval; | |
| 959 | 939 | x = *p << 7; | |
@@ -962,9 +942,7 @@ string_hash(PyStringObject *a) | |||
| 962 | 942 | x ^= a->ob_size; | |
| 963 | 943 | if (x == -1) | |
| 964 | 944 | x = -2; | |
| 965 | - #ifdef CACHE_HASH | ||
| 966 | 945 | a->ob_shash = x; | |
| 967 | - #endif | ||
| 968 | 946 | return x; | |
| 969 | 947 | } | |
| 970 | 948 | ||
@@ -2730,14 +2708,10 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |||
| 2730 | 2708 | pnew = type->tp_alloc(type, n); | |
| 2731 | 2709 | if (pnew != NULL) { | |
| 2732 | 2710 | memcpy(PyString_AS_STRING(pnew), PyString_AS_STRING(tmp), n+1); | |
| 2733 | - #ifdef CACHE_HASH | ||
| 2734 | 2711 | ((PyStringObject *)pnew)->ob_shash = | |
| 2735 | 2712 | ((PyStringObject *)tmp)->ob_shash; | |
| 2736 | - #endif | ||
| 2737 | - #ifdef INTERN_STRINGS | ||
| 2738 | 2713 | ((PyStringObject *)pnew)->ob_sinterned = | |
| 2739 | 2714 | ((PyStringObject *)tmp)->ob_sinterned; | |
| 2740 | - #endif | ||
| 2741 | 2715 | } | |
| 2742 | 2716 | Py_DECREF(tmp); | |
| 2743 | 2717 | return pnew; | |
@@ -3579,7 +3553,6 @@ PyString_Format(PyObject *format, PyObject *args) | |||
| 3579 | 3553 | } | |
| 3580 | 3554 | ||
| 3581 | 3555 | ||
| 3582 | - #ifdef INTERN_STRINGS | ||
| 3583 | 3556 | ||
| 3584 | 3557 | /* This dictionary will leak at PyString_Fini() time. That's acceptable | |
| 3585 | 3558 | * because PyString_Fini() specifically frees interned strings that are | |
@@ -3656,8 +3629,6 @@ PyString_InternFromString(const char *cp) | |||
| 3656 | 3629 | return s; | |
| 3657 | 3630 | } | |
| 3658 | 3631 | ||
| 3659 | - #endif | ||
| 3660 | - | ||
| 3661 | 3632 | void | |
| 3662 | 3633 | PyString_Fini(void) | |
| 3663 | 3634 | { | |
@@ -3670,7 +3641,6 @@ PyString_Fini(void) | |||
| 3670 | 3641 | Py_XDECREF(nullstring); | |
| 3671 | 3642 | nullstring = NULL; | |
| 3672 | 3643 | #endif | |
| 3673 | - #ifdef INTERN_STRINGS | ||
| 3674 | 3644 | if (interned) { | |
| 3675 | 3645 | int pos, changed; | |
| 3676 | 3646 | PyObject *key, *value; | |
@@ -3685,10 +3655,8 @@ PyString_Fini(void) | |||
| 3685 | 3655 | } | |
| 3686 | 3656 | } while (changed); | |
| 3687 | 3657 | } | |
| 3688 | - #endif | ||
| 3689 | 3658 | } | |
| 3690 | 3659 | ||
| 3691 | - #ifdef INTERN_STRINGS | ||
| 3692 | 3660 | void _Py_ReleaseInternedStrings(void) | |
| 3693 | 3661 | { | |
| 3694 | 3662 | if (interned) { | |
@@ -3698,4 +3666,3 @@ void _Py_ReleaseInternedStrings(void) | |||
| 3698 | 3666 | interned = NULL; | |
| 3699 | 3667 | } | |
| 3700 | 3668 | } | |
| 3701 | - #endif /* INTERN_STRINGS */ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -978,7 +978,6 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen, | |||
| 978 | 978 | if (strlen(buf) != len) | |
| 979 | 979 | continue; /* v contains '\0' */ | |
| 980 | 980 | #ifdef macintosh | |
| 981 | - #ifdef INTERN_STRINGS | ||
| 982 | 981 | /* | |
| 983 | 982 | ** Speedup: each sys.path item is interned, and | |
| 984 | 983 | ** FindResourceModule remembers which items refer to | |
@@ -987,7 +986,6 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen, | |||
| 987 | 986 | */ | |
| 988 | 987 | PyString_InternInPlace(&PyList_GET_ITEM(path, i)); | |
| 989 | 988 | v = PyList_GET_ITEM(path, i); | |
| 990 | - #endif | ||
| 991 | 989 | if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) { | |
| 992 | 990 | static struct filedescr resfiledescr = | |
| 993 | 991 | {"", "", PY_RESOURCE}; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments