intobject.c: Save references to small integers, so that they can be

shared.  The default is to save references to the integers in
	the range -1..99.  The lower limit can be set by defining
	NSMALLNEGINTS (absolute value of smallest integer to be saved)
	and NSMALLPOSINTS (1 more than the largest integer to be
	saved).
tupleobject.c: Save a reference to the empty tuple to be returned
	whenever a tuple of size 0 is requested.  Tuples of size 1
	upto, but not including, MAXSAVESIZE (default 20) are put in
	free lists when deallocated.  When MAXSAVESIZE equals 1, only
	share references to the empty tuple, when MAXSAVESIZE equals
	0, don't include the code at all and revert to the old
	behavior.
object.c: Print some more statistics when COUNT_ALLOCS is defined.
This commit is contained in:
Sjoerd Mullender 1993-10-15 16:18:48 +00:00
parent 21d335ed9e
commit 842d2ccdcd
3 changed files with 95 additions and 7 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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