[Python-checkins] r58623 - in python/trunk: Misc/NEWS Python/bltinmodule.c

raymond.hettinger python-checkins at python.org
Wed Oct 24 03:28:33 CEST 2007


Author: raymond.hettinger
Date: Wed Oct 24 03:28:33 2007
New Revision: 58623

Modified:
   python/trunk/Misc/NEWS
   python/trunk/Python/bltinmodule.c
Log:
Optimize sum() for integer and float inputs.

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Wed Oct 24 03:28:33 2007
@@ -12,6 +12,8 @@
 Core and builtins
 -----------------
 
+- optimize the performance of builtin.sum().
+
 - Fix warnings found by the new version of the Coverity checker.
 
 - The enumerate() builtin function is no longer bounded to sequences smaller

Modified: python/trunk/Python/bltinmodule.c
==============================================================================
--- python/trunk/Python/bltinmodule.c	(original)
+++ python/trunk/Python/bltinmodule.c	Wed Oct 24 03:28:33 2007
@@ -2066,6 +2066,76 @@
 		Py_INCREF(result);
 	}
 
+#ifndef SLOW_SUM
+	/* Fast addition by keeping temporary sums in C instead of new Python objects.
+           Assumes all inputs are the same type.  If the assumption fails, default
+           to the more general routine.
+	*/
+	if (PyInt_CheckExact(result)) {
+		long i_result = PyInt_AS_LONG(result);
+		Py_DECREF(result);
+		result = NULL;
+		while(result == NULL) {
+			item = PyIter_Next(iter);
+			if (item == NULL) {
+				Py_DECREF(iter);
+				if (PyErr_Occurred())
+					return NULL;
+    				return PyInt_FromLong(i_result);
+			}
+        		if (PyInt_CheckExact(item)) {
+            			long b = PyInt_AS_LONG(item);
+				long x = i_result + b;
+				if ((x^i_result) >= 0 || (x^b) >= 0) {
+					i_result = x;
+					Py_DECREF(item);
+					continue;
+				}
+			}
+			/* Either overflowed or is not an int. Restore real objects and process normally */
+			result = PyInt_FromLong(i_result);
+			temp = PyNumber_Add(result, item);
+			Py_DECREF(result);
+			Py_DECREF(item);
+			result = temp;
+			if (result == NULL) {
+				Py_DECREF(iter);
+				return NULL;
+			}
+		}
+	}
+
+	if (PyFloat_CheckExact(result)) {
+		double f_result = PyFloat_AS_DOUBLE(result);
+		Py_DECREF(result);
+		result = NULL;
+		while(result == NULL) {
+			item = PyIter_Next(iter);
+			if (item == NULL) {
+				Py_DECREF(iter);
+				if (PyErr_Occurred())
+					return NULL;
+    				return PyFloat_FromDouble(f_result);
+			}
+        		if (PyFloat_CheckExact(item)) {
+				PyFPE_START_PROTECT("add", return 0)
+				f_result += PyFloat_AS_DOUBLE(item);
+				PyFPE_END_PROTECT(a)
+				continue;
+			}
+			result = PyFloat_FromDouble(f_result);
+			temp = PyNumber_Add(result, item);
+			Py_DECREF(result);
+			Py_DECREF(item);
+			result = temp;
+			if (result == NULL) {
+				Py_DECREF(iter);
+				return NULL;
+			}
+		}
+	}
+#endif
+
 	for(;;) {
 		item = PyIter_Next(iter);
 		if (item == NULL) {


More information about the Python-checkins mailing list