Variant of SF patch 103252: Startup optimize: read *.pyc as string, not with getc().

This commit is contained in:
Tim Peters 2001-01-18 04:39:16 +00:00
parent 60f42b50d8
commit 691e0e95de
2 changed files with 48 additions and 0 deletions

View File

@ -179,6 +179,7 @@ Greg Humphreys
Jeremy Hylton
John Interrante
Ben Jackson
Paul Jackson
Jack Jansen
Bill Janssen
Drew Jenkins

View File

@ -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 *