diff options
| author | Tim Peters <tim.peters@gmail.com> | 2001-01-18 04:39:16 +0000 | 
|---|---|---|
| committer | Tim Peters <tim.peters@gmail.com> | 2001-01-18 04:39:16 +0000 | 
| commit | 691e0e95de064f04675018ecbf0b74f709253271 (patch) | |
| tree | dee92c6ccba4336418f2363977756a3e0866e336 | |
| parent | 60f42b50d894d3c9798c50e063ae758a1a5987a2 (diff) | |
| download | cpython-git-691e0e95de064f04675018ecbf0b74f709253271.tar.gz | |
Variant of SF patch 103252: Startup optimize: read *.pyc as string, not with getc().
| -rw-r--r-- | Misc/ACKS | 1 | ||||
| -rw-r--r-- | Python/marshal.c | 47 | 
2 files changed, 48 insertions, 0 deletions
@@ -179,6 +179,7 @@ Greg Humphreys  Jeremy Hylton  John Interrante  Ben Jackson +Paul Jackson  Jack Jansen  Bill Janssen  Drew Jenkins diff --git a/Python/marshal.c b/Python/marshal.c index a9b3ed1653..684a8b4c08 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -606,16 +606,63 @@ PyMarshal_ReadLongFromFile(FILE *fp)  	return r_long(&rf);  } +#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  }  PyObject *  | 
