Commit dd159ce6 authored by Stefan Krah's avatar Stefan Krah

Speed up _decimal by 30-40% for numerical workloads by improving the cache

locality for regularly sized coefficients.
parent 94ef3e4c
...@@ -55,9 +55,13 @@ ...@@ -55,9 +55,13 @@
#define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x #define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x
/* _Py_DEC_MINALLOC >= MPD_MINALLOC */
#define _Py_DEC_MINALLOC 4
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
mpd_t *dec; mpd_t dec;
mpd_uint_t data[_Py_DEC_MINALLOC];
} PyDecObject; } PyDecObject;
typedef struct { typedef struct {
...@@ -90,7 +94,7 @@ static PyTypeObject PyDecContextManager_Type; ...@@ -90,7 +94,7 @@ static PyTypeObject PyDecContextManager_Type;
#define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type) #define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type)
#define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_Type) #define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_Type)
#define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type) #define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type)
#define MPD(v) (((PyDecObject *)v)->dec) #define MPD(v) (&((PyDecObject *)v)->dec)
#define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags) #define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags)
#define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags) #define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags)
#define CTX(v) (&((PyDecContextObject *)v)->ctx) #define CTX(v) (&((PyDecContextObject *)v)->ctx)
...@@ -1789,35 +1793,33 @@ static PyTypeObject PyDecContextManager_Type = ...@@ -1789,35 +1793,33 @@ static PyTypeObject PyDecContextManager_Type =
static PyObject * static PyObject *
PyDecType_New(PyTypeObject *type) PyDecType_New(PyTypeObject *type)
{ {
PyObject *dec; PyDecObject *dec;
if (type == &PyDec_Type) { if (type == &PyDec_Type) {
dec = (PyObject *)PyObject_New(PyDecObject, &PyDec_Type); dec = PyObject_New(PyDecObject, &PyDec_Type);
} }
else { else {
dec = type->tp_alloc(type, 0); dec = (PyDecObject *)type->tp_alloc(type, 0);
} }
if (dec == NULL) { if (dec == NULL) {
return NULL; return NULL;
} }
MPD(dec) = mpd_qnew(); MPD(dec)->flags = MPD_STATIC|MPD_STATIC_DATA;
if (MPD(dec) == NULL) { MPD(dec)->exp = 0;
Py_DECREF(dec); MPD(dec)->digits = 0;
PyErr_NoMemory(); MPD(dec)->len = 0;
return NULL; MPD(dec)->alloc = _Py_DEC_MINALLOC;
} MPD(dec)->data = dec->data;
return dec; return (PyObject *)dec;
} }
#define dec_alloc() PyDecType_New(&PyDec_Type) #define dec_alloc() PyDecType_New(&PyDec_Type)
static void static void
dec_dealloc(PyObject *dec) dec_dealloc(PyObject *dec)
{ {
if (MPD(dec)) {
mpd_del(MPD(dec)); mpd_del(MPD(dec));
}
Py_TYPE(dec)->tp_free(dec); Py_TYPE(dec)->tp_free(dec);
} }
...@@ -5342,7 +5344,7 @@ PyInit__decimal(void) ...@@ -5342,7 +5344,7 @@ PyInit__decimal(void)
mpd_reallocfunc = PyMem_Realloc; mpd_reallocfunc = PyMem_Realloc;
mpd_callocfunc = mpd_callocfunc_em; mpd_callocfunc = mpd_callocfunc_em;
mpd_free = PyMem_Free; mpd_free = PyMem_Free;
mpd_setminalloc(4); mpd_setminalloc(_Py_DEC_MINALLOC);
/* Init types */ /* Init types */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment