]> granicus.if.org Git - python/commitdiff
Speed up _decimal by 30-40% for numerical workloads by improving the cache
authorStefan Krah <skrah@bytereef.org>
Mon, 9 Apr 2012 18:24:57 +0000 (20:24 +0200)
committerStefan Krah <skrah@bytereef.org>
Mon, 9 Apr 2012 18:24:57 +0000 (20:24 +0200)
locality for regularly sized coefficients.

Modules/_decimal/_decimal.c

index 91aac87c254f30fc7842ca6fbc8965f0ab89dedf..c3d20dfd8923f37742cd449bc19491e3ba854795 100644 (file)
 #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 {
     PyObject_HEAD
-    mpd_t *dec;
+    mpd_t dec;
+    mpd_uint_t data[_Py_DEC_MINALLOC];
 } PyDecObject;
 
 typedef struct {
@@ -90,7 +94,7 @@ static PyTypeObject PyDecContextManager_Type;
 #define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type)
 #define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_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 SdFlags(v) (*((PyDecSignalDictObject *)v)->flags)
 #define CTX(v) (&((PyDecContextObject *)v)->ctx)
@@ -1789,35 +1793,33 @@ static PyTypeObject PyDecContextManager_Type =
 static PyObject *
 PyDecType_New(PyTypeObject *type)
 {
-    PyObject *dec;
+    PyDecObject *dec;
 
     if (type == &PyDec_Type) {
-        dec = (PyObject *)PyObject_New(PyDecObject, &PyDec_Type);
+        dec = PyObject_New(PyDecObject, &PyDec_Type);
     }
     else {
-        dec = type->tp_alloc(type, 0);
+        dec = (PyDecObject *)type->tp_alloc(type, 0);
     }
     if (dec == NULL) {
         return NULL;
     }
 
-    MPD(dec) = mpd_qnew();
-    if (MPD(dec) == NULL) {
-        Py_DECREF(dec);
-        PyErr_NoMemory();
-        return NULL;
-    }
+    MPD(dec)->flags = MPD_STATIC|MPD_STATIC_DATA;
+    MPD(dec)->exp = 0;
+    MPD(dec)->digits = 0;
+    MPD(dec)->len = 0;
+    MPD(dec)->alloc = _Py_DEC_MINALLOC;
+    MPD(dec)->data = dec->data;
 
-    return dec;
+    return (PyObject *)dec;
 }
 #define dec_alloc() PyDecType_New(&PyDec_Type)
 
 static void
 dec_dealloc(PyObject *dec)
 {
-    if (MPD(dec)) {
-        mpd_del(MPD(dec));
-    }
+    mpd_del(MPD(dec));
     Py_TYPE(dec)->tp_free(dec);
 }
 
@@ -5342,7 +5344,7 @@ PyInit__decimal(void)
     mpd_reallocfunc = PyMem_Realloc;
     mpd_callocfunc = mpd_callocfunc_em;
     mpd_free = PyMem_Free;
-    mpd_setminalloc(4);
+    mpd_setminalloc(_Py_DEC_MINALLOC);
 
 
     /* Init types */