Speed of Python vs. Perl

Paul Jackson pj at sgi.com
Fri Jan 12 23:15:10 EST 2001


I (pj) wrote:
|> So these two changes account for almost half the Perl win
|> in startup time, at least on my current system.

That was with Python 1.5.2 ("hello world" time improved from
180 to 130 msec with these two changes).

With BeOpen-Python-2.0, these two changes make less of a
difference, improving the "hello world" time from 210 msec to
190 msec, approximately, on my Irix system.


So these two changes make less difference to Python 2.0.

The biggest apparent remaining user-level cpu time sinks seem
to be in:

   * fixstate(), in Parser/acceler.c

   * the threaded malloc calls, some of which originate in fixstate()

   * lookdict_string, Objects/dictobject.c


===

Here's a patch for these two changes, this time for Python 2.0:

===


--- compile.c.orig	Mon Oct 16 14:49:29 2000
+++ compile.c	Fri Jan 12 19:54:38 2001
@@ -164,6 +164,26 @@
 #define NAME_CHARS \
 	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
 
+/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
+
+static int
+all_name_chars(char *s)
+{
+	static char ok_name_char[256];
+	static char *name_chars = NAME_CHARS;
+
+	if (ok_name_char[*name_chars] == 0) {
+		char *p;
+		for (p = name_chars; *p; p++)
+			ok_name_char[*p] = 1;
+	}
+	while (*s) {
+		if (ok_name_char[*s++] == 0)
+			return 0;
+	}
+	return 1;
+}
+
 PyCodeObject *
 PyCode_New(int argcount, int nlocals, int stacksize, int flags,
 	   PyObject *code, PyObject *consts, PyObject *names,
@@ -218,8 +238,7 @@
 		if (!PyString_Check(v))
 			continue;
 		p = PyString_AsString(v);
-		if (strspn(p, NAME_CHARS)
-		    != (size_t)PyString_Size(v))
+		if(!all_name_chars(p))
 			continue;
 		PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
 	}


--- marshal.c.orig	Mon Oct 16 14:49:29 2000
+++ marshal.c	Fri Jan 12 19:55:08 2001
@@ -8,6 +8,8 @@
 #include "longintrepr.h"
 #include "compile.h"
 #include "marshal.h"
+#include <sys/types.h>
+#include <sys/stat.h>
 
 /* High water mark to determine when the marshalled object is dangerously deep
  * and risks coring the interpreter.  When the object stack gets this deep,
@@ -608,13 +610,39 @@
 	return r_long(&rf);
 }
 
+
+static off_t
+getfilesize(FILE *fp)
+{
+	struct stat st;
+	if (fstat(fileno(fp), &st) != 0)
+		return -1;
+	else
+		return st.st_size;
+}
+
 PyObject *
 PyMarshal_ReadObjectFromFile(FILE *fp)
 {
 	RFILE rf;
+	off_t filesize;
 	if (PyErr_Occurred()) {
 		fprintf(stderr, "XXX rd_object called with exception set\n");
 		return NULL;
+	}
+#	define FILEBUFSIZE 65536
+	filesize = getfilesize(fp);
+	if (filesize > 0 && filesize < FILEBUFSIZE) {
+		char *buf;
+		buf = malloc(filesize);
+		if (buf > 0) {
+			PyObject *pop;
+			size_t rsz;
+			rsz = fread(buf, 1, filesize, fp);
+			pop = PyMarshal_ReadObjectFromString(buf, rsz);
+			free(buf);
+			return pop;
+		}
 	}
 	rf.fp = fp;
 	return r_object(&rf);
-- 
                          I won't rest till it's the best ...
                          Manager, Linux System Software
                          Paul Jackson <pj at sgi.com> 1.650.933.1373



More information about the Python-list mailing list