[Python-checkins] CVS: python/dist/src/Python marshal.c,1.58,1.59

Tim Peters tim_one@users.sourceforge.net
Wed, 17 Jan 2001 20:39:18 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv21041/python/dist/src/Python

Modified Files:
	marshal.c 
Log Message:
Variant of SF patch 103252: Startup optimize: read *.pyc as string, not with getc().


Index: marshal.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -C2 -r1.58 -r1.59
*** marshal.c	2000/11/14 20:44:53	1.58
--- marshal.c	2001/01/18 04:39:16	1.59
***************
*** 607,620 ****
--- 607,667 ----
  }
  
+ #ifdef HAVE_FSTAT
+ /* Return size of file in bytes; < 0 if unknown. */
+ static off_t
+ getfilesize(FILE *fp)
+ {
+ 	struct stat st;
+ 	if (fstat(fileno(fp), &st) != 0)
+ 		return -1;
+ 	else
+ 		return st.st_size;
+ }
+ #endif
+  
+ /* If we can get the size of the file up-front, and it's reasonably small,
+  * read it in one gulp and delegate to ...FromString() instead.  Much quicker
+  * than reading a byte at a time from file; speeds .pyc imports.
+  */
  PyObject *
  PyMarshal_ReadObjectFromFile(FILE *fp)
  {
+ /* 75% of 2.1's .pyc files can exploit SMALL_FILE_LIMIT.
+  * REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc.
+  */
+ #define SMALL_FILE_LIMIT (1L << 14)
+ #define REASONABLE_FILE_LIMIT (1L << 18)
  	RFILE rf;
+ #ifdef HAVE_FSTAT
+ 	off_t filesize;
+ #endif
  	if (PyErr_Occurred()) {
  		fprintf(stderr, "XXX rd_object called with exception set\n");
  		return NULL;
  	}
+ #ifdef HAVE_FSTAT
+ 	filesize = getfilesize(fp);
+ 	if (filesize > 0) {
+ 		char buf[SMALL_FILE_LIMIT];
+ 		char* pBuf = NULL;
+ 		if (filesize <= SMALL_FILE_LIMIT)
+ 			pBuf = buf;
+ 		else if (filesize <= REASONABLE_FILE_LIMIT)
+ 			pBuf = (char *)PyMem_MALLOC(filesize);
+ 		if (pBuf != NULL) {
+ 			PyObject* v;
+ 			size_t n = fread(pBuf, 1, filesize, fp);
+ 			v = PyMarshal_ReadObjectFromString(pBuf, n);
+ 			if (pBuf != buf)
+ 				PyMem_FREE(pBuf);
+ 			return v;
+ 		}
+ 		
+ 	}
+ #endif
  	rf.fp = fp;
  	return r_object(&rf);
+ #undef SMALL_FILE_LIMIT
+ #undef REASONABLE_FILE_LIMIT
  }