From a4c925e7cd874d88e1e70b7510b697a7fd17c0b2 Mon Sep 17 00:00:00 2001 From: ahgamut <41098605+ahgamut@users.noreply.github.com> Date: Mon, 20 Jun 2022 02:18:24 +0530 Subject: [PATCH] shave off stat syscalls by rearranging imports the hardest import method format to speed up is the "from x import y", because I have no idea whether y is a module or not. If y is a module, "from x import y" behaves similarly to the format "import x.y; y = x.y", which means I can bypass some checks by doing the import and equality separately. If y is a function, "from x import y" is not equivalent to the above format, and the import will trigger a ModuleNotFoundError. Unfortunately I can't check for or propagate such errors during the default APE startup without adding a whole bunch of checks, so I'd prefer to avoid these kinds of imports unless absolutely necessary. in this PR I avoid three such function imports in io.py and ntpath.py. The fix is to import the module wholesale (which happens underneath anyway) and then just check for the attribute - "import x; y = x.y", essentially similar to how it would be if y was a module. --- third_party/python/Lib/io.py | 6 ++---- third_party/python/Lib/ntpath.py | 15 ++++++++------- third_party/python/Python/import.c | 6 ++---- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/third_party/python/Lib/io.py b/third_party/python/Lib/io.py index 968ee5073..fbd0fe7d2 100644 --- a/third_party/python/Lib/io.py +++ b/third_party/python/Lib/io.py @@ -92,8 +92,6 @@ for klass in (StringIO, TextIOWrapper): del klass try: - from _io import _WindowsConsoleIO -except ImportError: + RawIOBase.register(_io._WindowsConsoleIO) +except AttributeError: pass -else: - RawIOBase.register(_WindowsConsoleIO) diff --git a/third_party/python/Lib/ntpath.py b/third_party/python/Lib/ntpath.py index 406f0441a..bcf83f09c 100644 --- a/third_party/python/Lib/ntpath.py +++ b/third_party/python/Lib/ntpath.py @@ -20,6 +20,7 @@ devnull = 'nul' import os import sys import stat +import posix import genericpath from genericpath import * @@ -276,8 +277,8 @@ def lexists(path): # common case: drive letter roots. The alternative which uses GetVolumePathName # fails if the drive letter is the result of a SUBST. try: - from posix import _getvolumepathname -except ImportError: + _getvolumepathname = posix._getvolumepathname +except AttributeError: _getvolumepathname = None def ismount(path): """Test whether a path is a mount point (a drive root, the root of a @@ -534,9 +535,9 @@ def _abspath_fallback(path): # Return an absolute path. try: - from posix import _getfullpathname + _getfullpathname = posix._getfullpathname -except ImportError: # not running on Windows - mock up something sensible +except AttributeError: # not running on Windows - mock up something sensible abspath = _abspath_fallback else: # use native Windows method on Windows @@ -664,7 +665,7 @@ try: # GetFinalPathNameByHandle is available starting with Windows 6.0. # Windows XP and non-Windows OS'es will mock _getfinalpathname. if sys.getwindowsversion()[:2] >= (6, 0): - from posix import _getfinalpathname + _getfinalpathname = posix._getfinalpathname else: raise ImportError except (AttributeError, ImportError, OSError): @@ -681,7 +682,7 @@ try: # attribute to tell whether or not the path is a directory. # This is overkill on Windows - just pass the path to GetFileAttributes # and check the attribute from there. - from posix import _isdir as isdir -except ImportError: + isdir = posix._isdir +except AttributeError: # Use genericpath.isdir as imported above. pass diff --git a/third_party/python/Python/import.c b/third_party/python/Python/import.c index edddd51f0..8519083e3 100644 --- a/third_party/python/Python/import.c +++ b/third_party/python/Python/import.c @@ -128,11 +128,8 @@ static initentry ZipEntries[] = { {"encodings.utf_8", {.inside_zip = 1, .is_package = 0}}, {"genericpath", {.inside_zip = 1, .is_package = 0}}, {"io", {.inside_zip = 1, .is_package = 0}}, - {"io._WindowsConsoleIO", {.inside_zip = 0, .is_package = 0}}, {"ntpath", {.inside_zip = 1, .is_package = 0}}, {"os", {.inside_zip = 1, .is_package = 0}}, - {"posix._getfullpathname", {.inside_zip = 0, .is_package = 0}}, - {"posix._isdir", {.inside_zip = 0, .is_package = 0}}, {"posixpath", {.inside_zip = 1, .is_package = 0}}, {"readline", {.inside_zip = 0, .is_package = 0}}, {"site", {.inside_zip = 1, .is_package = 0}}, @@ -2811,8 +2808,9 @@ static PyObject *CosmoImporter_find_spec(PyObject *cls, PyObject **args, key.tab = NULL; res = bsearch(&key, ZipCdir_Lookup.entries, ZipCdir_Lookup.n, sizeof(initentry), cmp_initentry); if (res) { - if (!res->inside_zip) + if (!res->inside_zip) { Py_RETURN_NONE; + } inside_zip = res->inside_zip; is_package = res->is_package; }