[Python-checkins] r51522 - in python/branches/int_unification: INTBENCH Modules/_testcapimodule.c Objects/longobject.c

martin.v.loewis python-checkins at python.org
Wed Aug 23 21:41:31 CEST 2006


Author: martin.v.loewis
Date: Wed Aug 23 21:41:30 2006
New Revision: 51522

Modified:
   python/branches/int_unification/INTBENCH
   python/branches/int_unification/Modules/_testcapimodule.c
   python/branches/int_unification/Objects/longobject.c
Log:
Special-case one-digit longs on allocation.
Add benchmark for integer addition.


Modified: python/branches/int_unification/INTBENCH
==============================================================================
--- python/branches/int_unification/INTBENCH	(original)
+++ python/branches/int_unification/INTBENCH	Wed Aug 23 21:41:30 2006
@@ -6,6 +6,8 @@
 Test 2: 1.696623s
 Test 3: 1.900683s
 Test 4: 5.307155s
+Test 6: 1.670252s
+Test 7: 1.910734s
 
 r51506 (int type dropped)
 Test 1: 4.134757s

Modified: python/branches/int_unification/Modules/_testcapimodule.c
==============================================================================
--- python/branches/int_unification/Modules/_testcapimodule.c	(original)
+++ python/branches/int_unification/Modules/_testcapimodule.c	Wed Aug 23 21:41:30 2006
@@ -731,7 +731,7 @@
 {
 	int i, k;
 	struct timeval start, stop;
-	PyObject *single, **multiple;
+	PyObject *single, **multiple, *op1, *result;
 
 	/* Test 1: Allocate and immediately deallocate
 	   many small integers */
@@ -785,6 +785,42 @@
 	gettimeofday(&stop, NULL);
 	print_delta(4, &start, &stop);
 
+	/* Test 5: Allocate many integers < 32000 */
+	multiple = malloc(sizeof(PyObject*) * 1000000);
+	gettimeofday(&start, NULL);
+	for(k=0; k < 20; k++) {
+		for(i=0; i < 1000000; i++) {
+			multiple[i] = PyInt_FromLong(i+1000);
+		}
+		for(i=0; i < 1000000; i++) {
+			Py_DECREF(multiple[i]);
+		}
+	}
+	gettimeofday(&stop, NULL);
+	print_delta(5, &start, &stop);
+
+	/* Test 6: Perform small int addition */
+	op1 = PyInt_FromLong(1);
+	gettimeofday(&start, NULL);
+	for(i=0; i < 10000000; i++) {
+		result = PyNumber_Add(op1, op1);
+		Py_DECREF(result);
+	}
+	gettimeofday(&stop, NULL);
+	Py_DECREF(op1);
+	print_delta(6, &start, &stop);
+
+	/* Test 7: Perform medium int addition */
+	op1 = PyInt_FromLong(1000);
+	gettimeofday(&start, NULL);
+	for(i=0; i < 10000000; i++) {
+		result = PyNumber_Add(op1, op1);
+		Py_DECREF(result);
+	}
+	gettimeofday(&stop, NULL);
+	Py_DECREF(op1);
+	print_delta(7, &start, &stop);
+
 	Py_INCREF(Py_None);
 	return Py_None;
 }

Modified: python/branches/int_unification/Objects/longobject.c
==============================================================================
--- python/branches/int_unification/Objects/longobject.c	(original)
+++ python/branches/int_unification/Objects/longobject.c	Wed Aug 23 21:41:30 2006
@@ -29,7 +29,7 @@
 static inline PyObject *
 get_small_int(int ival)
 {
-	PyObject *v = small_ints + ival + NSMALLNEGINTS;
+	PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS);
 	Py_INCREF(v);
 #ifdef COUNT_ALLOCS
 	if (ival >= 0)
@@ -37,7 +37,7 @@
 	else
 		quick_neg_int_allocs++;
 #endif
-	return (PyObject *) v;
+	return v;
 }
 #define CHECK_SMALL_INT(ival) \
 	do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \
@@ -47,6 +47,7 @@
 #else
 #define CHECK_SMALL_INT(ival)
 #endif
+
 /* For long multiplication, use the O(N**2) school algorithm unless
  * both operands contain more than KARATSUBA_CUTOFF digits (this
  * being an internal Python long digit, in base BASE).
@@ -152,6 +153,16 @@
 		negative = 1;
 	}
 
+	if (ival < BASE) {
+		/* Fast path for single-digits ints */
+		v = PyObject_NEW_VAR(PyLongObject, &PyLong_Type, 1);
+		if (v) {
+			v->ob_size = negative ? -1 : 1;
+			v->ob_digit[0] = ival;
+		}
+		return (PyObject*)v;
+	}
+
 	/* Count the number of Python digits.
 	   We used to pick 5 ("big enough for anything"), but that's a
 	   waste of time and space given that 5*15 = 75 bits are rarely
@@ -183,7 +194,8 @@
 	unsigned long t;
 	int ndigits = 0;
 
-	CHECK_SMALL_INT(ival);
+	if (ival < BASE)
+		return PyLong_FromLong(ival);
 	/* Count the number of Python digits. */
 	t = (unsigned long)ival;
 	while (t) {
@@ -216,11 +228,11 @@
 			"cannot convert float infinity to long");
 		return NULL;
 	}
+	CHECK_SMALL_INT((int)dval);
 	if (dval < 0.0) {
 		neg = 1;
 		dval = -dval;
 	}
-	CHECK_SMALL_INT((int)dval);
 	frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
 	if (expo <= 0)
 		return PyLong_FromLong(0L);
@@ -948,7 +960,8 @@
 	unsigned PY_LONG_LONG t;
 	int ndigits = 0;
 
-	CHECK_SMALL_INT(ival);
+	if (ival < BASE)
+		return PyLong_FromLong(ival);
 	/* Count the number of Python digits. */
 	t = (unsigned PY_LONG_LONG)ival;
 	while (t) {
@@ -974,7 +987,8 @@
 {
 	Py_ssize_t bytes = ival;
 	int one = 1;
-	CHECK_SMALL_INT(ival);
+	if (ival < BASE)
+		return PyLong_FromLong(ival);
 	return _PyLong_FromByteArray(
 			(unsigned char *)&bytes,
 			SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);
@@ -987,7 +1001,8 @@
 {
 	size_t bytes = ival;
 	int one = 1;
-	CHECK_SMALL_INT(ival);
+	if (ival < BASE)
+		return PyLong_FromLong(ival);
 	return _PyLong_FromByteArray(
 			(unsigned char *)&bytes,
 			SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);


More information about the Python-checkins mailing list