Optimize makedirs on Windows
@mdboom arbeitet bereits daran.
Seit 28.2.2023.
Bewertung
Dieses Issue wurde noch nicht bewertet.
Beschreibung
I've been working to improve the performance of some Python workflows on Windows, and I found that a noticeable amount of time was being spent in makedirs.
I some more profiling on the venv create scenario, and learned that roughly 1/3rd of the stat cost can be solely attributed to the exists check in makedirs (src). (Which is being called by compile here, and from my cursory glance at that code, it should simply be passing exist_ok=True rather than catching FileExistsError, right?). What makes this especially wasteful is that this run contained 1451 calls to makedirs and 1455 calls to makedir, implying that the exists check was making things worse, rather than helping. Put another way, exists is taking nearly as much time as mkdir here.
While it's true that if/when we get GetFileInformationByPath(), it should make stat calls much faster, that will only benefit the minority of users running a new version of Windows containing this new API. Therefore, it makes sense for us to improve the state of things for users running an older Windows, when practical.
And in this case, we should allow makedirs on Windows to execute in an idiomatically performant way. And that is to simply call CreateDirectoryW() and selectively ignore ERROR_ALREADY_EXISTS.
CreateDirectoryW() isn't cheap, but in the case of an existing directory, I don't think it's any worse than Windows' stat implementation that uses CreateFileW(). And in the case of when the directory doesn't exist and needs to be created, it will be significantly faster to make the single call.
It's probably worth splitting off a Windows-specific implementation of makedirs into the native side (posixmodule.c ?) so that we don't depend on raising a relatively expensive FileNotFoundError.
The non-Windows implementation should still use the cheap and reliable exists() and isdir().
(Forked from discussion on #101196)
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 36k
- Ø Merge
- 1 T. 9 Std.
- Gemergte PRs (30 T.)
- 558
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus python/cpython
-
docs pending
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
-
stdlib type-feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
-
stdlib type-feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
-
build type-bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
-
stdlib topic-email type-feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
Ähnliche Issues
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 90/100
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 86/100
zostera/django-bootstrap4#894 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
use-agent-os/agent-os#3276 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
zephyrproject-rtos/zephyr#119726 ·
-
area/auth bug comp/agent P3 platform/discord type/security
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
NousResearch/hermes-agent#117848 ·