summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Objects/intobject.c37
-rw-r--r--Objects/object.c10
-rw-r--r--Objects/tupleobject.c55
3 files changed, 95 insertions, 7 deletions
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 816a411..6fcbe69 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -75,12 +75,42 @@ fill_free_list()
}
static intobject *free_list = NULL;
+#ifndef NSMALLPOSINTS
+#define NSMALLPOSINTS 100
+#endif
+#ifndef NSMALLNEGINTS
+#define NSMALLNEGINTS 1
+#endif
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+/* References to small integers are saved in this array so that they
+ can be shared.
+ The integers that are saved are those in the range
+ -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
+*/
+static intobject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
+#endif
+#ifdef COUNT_ALLOCS
+int quick_int_allocs, quick_neg_int_allocs;
+#endif
object *
newintobject(ival)
long ival;
{
register intobject *v;
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+ if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS &&
+ (v = small_ints[ival + NSMALLNEGINTS]) != NULL) {
+ INCREF(v);
+#ifdef COUNT_ALLOCS
+ if (ival >= 0)
+ quick_int_allocs++;
+ else
+ quick_neg_int_allocs++;
+#endif
+ return (object *) v;
+ }
+#endif
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
@@ -90,6 +120,13 @@ newintobject(ival)
v->ob_type = &Inttype;
v->ob_ival = ival;
NEWREF(v);
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+ if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
+ /* save this one for a following allocation */
+ INCREF(v);
+ small_ints[ival + NSMALLNEGINTS] = v;
+ }
+#endif
return (object *) v;
}
diff --git a/Objects/object.c b/Objects/object.c
index a20b24d..bc0aeed 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -36,15 +36,21 @@ long ref_total;
#ifdef COUNT_ALLOCS
static typeobject *type_list;
-
+extern int tuple_zero_allocs, fast_tuple_allocs;
+extern int quick_int_allocs, quick_neg_int_allocs;
void
dump_counts()
{
typeobject *tp;
for (tp = type_list; tp; tp = tp->tp_next)
- printf("%s %d %d %d\n", tp->tp_name, tp->tp_alloc, tp->tp_free,
+ printf("%s alloc'd: %d, freed: %d, max in use: %d\n",
+ tp->tp_name, tp->tp_alloc, tp->tp_free,
tp->tp_maxalloc);
+ printf("fast tuple allocs: %d, empty: %d\n", fast_tuple_allocs,
+ tuple_zero_allocs);
+ printf("fast int allocs: pos: %d, neg: %d\n", quick_int_allocs,
+ quick_neg_int_allocs);
}
void
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index fae9386..bc68744 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -26,6 +26,21 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h"
+#ifndef MAXSAVESIZE
+#define MAXSAVESIZE 20
+#endif
+
+#if MAXSAVESIZE > 0
+/* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
+ tuple () of which at most one instance will be allocated.
+*/
+static tupleobject *free_list[MAXSAVESIZE];
+#endif
+#ifdef COUNT_ALLOCS
+int fast_tuple_allocs;
+int tuple_zero_allocs;
+#endif
+
object *
newtupleobject(size)
register int size;
@@ -36,15 +51,39 @@ newtupleobject(size)
err_badcall();
return NULL;
}
- op = (tupleobject *)
- malloc(sizeof(tupleobject) + size * sizeof(object *));
- if (op == NULL)
- return err_nomem();
+#if MAXSAVESIZE > 0
+ if (size == 0 && free_list[0]) {
+ op = free_list[0];
+ INCREF(op);
+#ifdef COUNT_ALLOCS
+ tuple_zero_allocs++;
+#endif
+ return (object *) op;
+ }
+ if (0 < size && size < MAXSAVESIZE && (op = free_list[size]) != NULL) {
+ free_list[size] = (tupleobject *) op->ob_item[0];
+#ifdef COUNT_ALLOCS
+ fast_tuple_allocs++;
+#endif
+ } else
+#endif
+ {
+ op = (tupleobject *)
+ malloc(sizeof(tupleobject) + size * sizeof(object *));
+ if (op == NULL)
+ return err_nomem();
+ }
op->ob_type = &Tupletype;
op->ob_size = size;
for (i = 0; i < size; i++)
op->ob_item[i] = NULL;
NEWREF(op);
+#if MAXSAVESIZE > 0
+ if (size == 0) {
+ free_list[0] = op;
+ INCREF(op); /* extra INCREF so that this is never freed */
+ }
+#endif
return (object *) op;
}
@@ -113,7 +152,13 @@ tupledealloc(op)
if (op->ob_item[i] != NULL)
DECREF(op->ob_item[i]);
}
- free((ANY *)op);
+#if MAXSAVESIZE > 0
+ if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
+ op->ob_item[0] = (object *) free_list[op->ob_size];
+ free_list[op->ob_size] = op;
+ } else
+#endif
+ free((ANY *)op);
}
static int