[Python-checkins] r46343 - python/trunk/Objects/stringobject.c

andrew.dalke python-checkins at python.org
Fri May 26 17:21:04 CEST 2006


Author: andrew.dalke
Date: Fri May 26 17:21:01 2006
New Revision: 46343

Modified:
   python/trunk/Objects/stringobject.c
Log:
Eeked out another 3% or so performance in split whitespace by cleaning up the algorithm.


Modified: python/trunk/Objects/stringobject.c
==============================================================================
--- python/trunk/Objects/stringobject.c	(original)
+++ python/trunk/Objects/stringobject.c	Fri May 26 17:21:01 2006
@@ -1460,7 +1460,7 @@
 	else							\
 		Py_DECREF(str);
 
-#define SPLIT_ADD(data, left, right)				\
+#define SPLIT_ADD(data, left, right) {				\
 	str = PyString_FromStringAndSize((data) + (left),	\
 					 (right) - (left));	\
 	if (str == NULL)					\
@@ -1475,11 +1475,16 @@
 		else						\
 			Py_DECREF(str);				\
 	}							\
-	count++;
+	count++; }
 
 /* Always force the list to the expected size. */
 #define FIX_PREALLOC_SIZE(list) ((PyListObject *)list)->ob_size = count;		
 
+#define SKIP_SPACE(s, i, len)    { while (i<len &&  isspace(Py_CHARMASK(s[i]))) i++; }
+#define SKIP_NONSPACE(s, i, len) { while (i<len && !isspace(Py_CHARMASK(s[i]))) i++; }
+#define RSKIP_SPACE(s, i)        { while (i>=0  &&  isspace(Py_CHARMASK(s[i]))) i--; }
+#define RSKIP_NONSPACE(s, i)     { while (i>=0  && !isspace(Py_CHARMASK(s[i]))) i--; }
+
 static PyObject *
 split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxsplit)
 {
@@ -1490,23 +1495,22 @@
 	if (list == NULL)
 		return NULL;
 
-	for (i = j = 0; i < len; ) {
-		while (i < len && isspace(Py_CHARMASK(s[i])))
-			i++;
-		j = i;
-		while (i < len && !isspace(Py_CHARMASK(s[i])))
-			i++;
-		if (j < i) {
-			if (maxsplit-- <= 0)
-				break;
-			SPLIT_ADD(s, j, i);
-			while (i < len && isspace(Py_CHARMASK(s[i])))
-				i++;
-			j = i;
-		}
+	i = j = 0;
+
+	while (maxsplit-- > 0) {
+		SKIP_SPACE(s, i, len);
+		if (i==len) break;
+		j = i; i++;
+		SKIP_NONSPACE(s, i, len);
+		SPLIT_ADD(s, j, i);
 	}
-	if (j < len) {
-		SPLIT_ADD(s, j, len);
+
+	if (i < len) {
+		/* Only occurs when maxsplit was reached */
+		/* Skip any remaining whitespace and copy to end of string */
+		SKIP_SPACE(s, i, len);
+		if (i != len)
+			SPLIT_ADD(s, i, len);
 	}
 	FIX_PREALLOC_SIZE(list);
 	return list;
@@ -1680,23 +1684,22 @@
 	if (list == NULL)
 		return NULL;
 
-	for (i = j = len - 1; i >= 0; ) {
-		while (i >= 0 && isspace(Py_CHARMASK(s[i])))
-			i--;
-		j = i;
-		while (i >= 0 && !isspace(Py_CHARMASK(s[i])))
-			i--;
-		if (j > i) {
-			if (maxsplit-- <= 0)
-				break;
-			SPLIT_ADD(s, i + 1, j + 1);
-			while (i >= 0 && isspace(Py_CHARMASK(s[i])))
-				i--;
-			j = i;
-		}
-	}
-	if (j >= 0) {
-		SPLIT_ADD(s, 0, j + 1);
+	i = j = len-1;
+	
+	while (maxsplit-- > 0) {
+		RSKIP_SPACE(s, i);
+		if (i<0) break;
+		j = i; i--;
+		RSKIP_NONSPACE(s, i);
+		SPLIT_ADD(s, i + 1, j + 1);
+	}
+	if (i >= 0) {
+		/* Only occurs when maxsplit was reached */
+		/* Skip any remaining whitespace and copy to beginning of string */
+		RSKIP_SPACE(s, i);
+		if (i >= 0)
+			SPLIT_ADD(s, 0, i + 1);
+
 	}
 	FIX_PREALLOC_SIZE(list);
 	if (PyList_Reverse(list) < 0)


More information about the Python-checkins mailing list