You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Speedup posixpath.abspath() for relative paths #117587
The idea is working, but I don't know what to do now:
Work on getting posixpath.abspath() to work with the new builtin function, with all tests passing. If the performance is good enough, you could just rename the new builtin as _path_normpath_with_start(). Otherwise, implement it all in _path_abspath().
Reading through the posts in the issue, it is not clear to me if there is significant core dev support for this idea. It would surprise me if abspath() was used for hot code. The diff of the linked PR is considerable. Does the added complexity outweigh the cost of improving the performance of an API like abspath()?
I reckon it unlikely that abspath() is a performance bottleneck in anyone's code.
It's a slightly dangerous function too - it calls normpath() which can change the meaning of a path like symlink/... It would be a shame to double down on that behaviour by implementing it in C. OTOH I can't see any reasonable path towards fixing abspath().
Note that I also extended the capabilities of _Py_normpath_and_size(). We could expose the start and explicit_curdir parameters, but I want to discuss that later:
You can use start to faster normalise a path after joining with an already normalised path:
And explicit_curdir helps to avoid ambiguity: ./C:foo has a vastly different meaning than C:foo.
And @eryksun asked specifically to implement abspath() in C.
I reckon it unlikely that abspath() is a performance bottleneck in anyone's code.
I just don't like the fact that we're normalising the cwd which is already normalised. Otherwise I definitely wouldn't have implemented it in C (there are other functions which we would benefit more of). And making it faster certainly doesn't hurt, right? I think it's even faster now that I got rid of the Python wrapper.
And @eryksun asked specifically to implement abspath() in C.
We've implemented enough of the implementation in C in terms of normpath() and splitroot() that it becomes feasible. But if you want to expose a private _path_normpath_ex() that supports start and explicit_curdir, we could make use of that instead, and continue to implement abspath() itself in Python. (I'm not satisfied with the direction you've been pushed into with the implementation of the function in C, and backing off on that saves me the time of trying to implement a rewrite that would make everyone happy.)
When adding new code, we try hard to weigh a lot of different factors: performance, usefulness, maintainability, readability, code complexity, the number of lines added or subtracted, and backwards compatibility, to name a few. We also try to understand any opposition to a change; "why is my PR/issue being criticised or rejected?"
I do not think this change is worth it. Performance optimisations are nice, but only if the benefits outweigh the added cost. Adding a C implementation of existing Python code needs a really good reason. C code has a lot more maintenance overhead than Python code. If the added C code is already in a state where it needs refactoring, you're directly adding technical dept.
Moreover, there has been talk about rewriting C code in Python when the interpreter has become fast enough1. This should also be taken into account when considering to add C code.
@barneygale, what about implementing _path_normpath_ex() that supports start and explicit_curdir? Supporting explicit_curdir is important for Windows to avoid problems with DOS device names (e.g. "./con") and named streams on single-letter filenames (e.g. "/C:spam"). Supporting start is an improvement for POSIX to avoid having to re-normalize the already-normalized current directory.
Hmm, start is not a great API as it doesn't work well for bytes. normpath('foo', 'C:/bar') would be better, but would be difficult to implement on Windows. I'll make a new pull request just to implement explicit_curdir.
I'll make a new pull request just to implement explicit_curdir.
No; please do not pollute the already too long list of open PRs. Discuss any possible change in an actionable issue first. If you need to open an experimental PR, do so on your own fork. The CPython repo is not the place for experimentation.
Activity
nineteendo commentedon Apr 12, 2024
The idea is working, but I don't know what to do now:
eryksun commentedon Apr 12, 2024
Work on getting
posixpath.abspath()to work with the new builtin function, with all tests passing. If the performance is good enough, you could just rename the new builtin as_path_normpath_with_start(). Otherwise, implement it all in_path_abspath().nineteendo commentedon Apr 13, 2024
erlend-aasland commentedon May 30, 2024
Reading through the posts in the issue, it is not clear to me if there is significant core dev support for this idea. It would surprise me if
abspath()was used for hot code. The diff of the linked PR is considerable. Does the added complexity outweigh the cost of improving the performance of an API likeabspath()?@barneygale and @serhiy-storchaka: thoughts?
barneygale commentedon May 30, 2024
I reckon it unlikely that
abspath()is a performance bottleneck in anyone's code.It's a slightly dangerous function too - it calls
normpath()which can change the meaning of a path likesymlink/... It would be a shame to double down on that behaviour by implementing it in C. OTOH I can't see any reasonable path towards fixingabspath().nineteendo commentedon May 30, 2024
Note that I also extended the capabilities of
_Py_normpath_and_size(). We could expose thestartandexplicit_curdirparameters, but I want to discuss that later:startto faster normalise a path after joining with an already normalised path:explicit_curdirhelps to avoid ambiguity:./C:foohas a vastly different meaning thanC:foo.And @eryksun asked specifically to implement
abspath()in C.I just don't like the fact that we're normalising the cwd which is already normalised. Otherwise I definitely wouldn't have implemented it in C (there are other functions which we would benefit more of). And making it faster certainly doesn't hurt, right? I think it's even faster now that I got rid of the Python wrapper.
eryksun commentedon May 30, 2024
We've implemented enough of the implementation in C in terms of
normpath()andsplitroot()that it becomes feasible. But if you want to expose a private_path_normpath_ex()that supportsstartandexplicit_curdir, we could make use of that instead, and continue to implementabspath()itself in Python. (I'm not satisfied with the direction you've been pushed into with the implementation of the function in C, and backing off on that saves me the time of trying to implement a rewrite that would make everyone happy.)erlend-aasland commentedon May 30, 2024
When adding new code, we try hard to weigh a lot of different factors: performance, usefulness, maintainability, readability, code complexity, the number of lines added or subtracted, and backwards compatibility, to name a few. We also try to understand any opposition to a change; "why is my PR/issue being criticised or rejected?"
I do not think this change is worth it. Performance optimisations are nice, but only if the benefits outweigh the added cost. Adding a C implementation of existing Python code needs a really good reason. C code has a lot more maintenance overhead than Python code. If the added C code is already in a state where it needs refactoring, you're directly adding technical dept.
Moreover, there has been talk about rewriting C code in Python when the interpreter has become fast enough1. This should also be taken into account when considering to add C code.
Footnotes
https://github.com/faster-cpython/ideas/issues/91 ↩
erlend-aasland commentedon May 30, 2024
I'll leave it for Barney to decide if this issue should be kept open or if it should be closed.
barneygale commentedon May 30, 2024
Sorry @nineteendo, I don't think the C implementation is worth it on balance, for the same reasons as Erlend gave.
eryksun commentedon May 30, 2024
@barneygale, what about implementing
_path_normpath_ex()that supportsstartandexplicit_curdir? Supportingexplicit_curdiris important for Windows to avoid problems with DOS device names (e.g. "./con") and named streams on single-letter filenames (e.g. "/C:spam"). Supportingstartis an improvement for POSIX to avoid having to re-normalize the already-normalized current directory.nineteendo commentedon May 31, 2024
Hmm,
startis not a great API as it doesn't work well for bytes.normpath('foo', 'C:/bar')would be better, but would be difficult to implement on Windows. I'll make a new pull request just to implementexplicit_curdir.erlend-aasland commentedon May 31, 2024
No; please do not pollute the already too long list of open PRs. Discuss any possible change in an actionable issue first. If you need to open an experimental PR, do so on your own fork. The CPython repo is not the place for experimentation.
nineteendo commentedon May 31, 2024
I have already done that: #119826