diff options
-rw-r--r-- | Objects/intobject.c | 37 | ||||
-rw-r--r-- | Objects/object.c | 10 | ||||
-rw-r--r-- | Objects/tupleobject.c | 55 |
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 |