[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