| extern "C" { | |
| /* | |
| * Default int base conversion size limitation: Denial of Service prevention. | |
| * | |
| * Chosen such that this isn't wildly slow on modern hardware and so that | |
| * everyone's existing deployed numpy test suite passes before | |
| * https://github.com/numpy/numpy/issues/22098 is widely available. | |
| * | |
| * $ python -m timeit -s 's = "1"*4300' 'int(s)' | |
| * 2000 loops, best of 5: 125 usec per loop | |
| * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)' | |
| * 1000 loops, best of 5: 311 usec per loop | |
| * (zen2 cloud VM) | |
| * | |
| * 4300 decimal digits fits a ~14284 bit number. | |
| */ | |
| /* | |
| * Threshold for max digits check. For performance reasons int() and | |
| * int.__str__() don't checks values that are smaller than this | |
| * threshold. Acts as a guaranteed minimum size limit for bignums that | |
| * applications can expect from CPython. | |
| * | |
| * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))' | |
| * 20000 loops, best of 5: 12 usec per loop | |
| * | |
| * "640 digits should be enough for anyone." - gps | |
| * fits a ~2126 bit decimal number. | |
| */ | |
| // Don't call this function but _PyLong_GetZero() and _PyLong_GetOne() | |
| static inline PyObject* __PyLong_GetSmallInt_internal(int value) | |
| { | |
| PyInterpreterState *interp = _PyInterpreterState_GET(); | |
| assert(-_PY_NSMALLNEGINTS <= value && value < _PY_NSMALLPOSINTS); | |
| size_t index = _PY_NSMALLNEGINTS + value; | |
| PyObject *obj = (PyObject*)interp->small_ints[index]; | |
| // _PyLong_GetZero(), _PyLong_GetOne() and get_small_int() must not be | |
| // called before _PyLong_Init() nor after _PyLong_Fini(). | |
| assert(obj != NULL); | |
| return obj; | |
| } | |
| // Return a borrowed reference to the zero singleton. | |
| // The function cannot return NULL. | |
| static inline PyObject* _PyLong_GetZero(void) | |
| { return __PyLong_GetSmallInt_internal(0); } | |
| // Return a borrowed reference to the one singleton. | |
| // The function cannot return NULL. | |
| static inline PyObject* _PyLong_GetOne(void) | |
| { return __PyLong_GetSmallInt_internal(1); } | |
| } | |