-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
isSymlink could be much faster if using lstat directly #400
Conversation
great idea, need to make sure it works on all platforms |
@swift-ci test |
@parkera is this something that can be addressed in foundation? |
Perhaps, depending on what platforms are involved here. We should look at the full trace and see what |
@kperryua You had some ideas on how to do this using Foundation instead, could you elaborate more here? |
From the slack conversation:
|
Unfortunately accessing |
Can you spindump the difference for me? When I checked last week it was demonstrably faster than the attributesOfItem implementation that makes multiple syscalls. |
@kperryua not sure how to spin dump the diff for you, but I followed the instructions in the forum thread and it was trivial to reproduce. Running this (on Sonoma b2 this time) |
I didn't realize this was dependent on swift-corelibs-foundation, which has a completely different implementation than Darwin's Foundation.framework. The SCL-Foundation implementation of URL resource values is in fact still not as efficient as it could be compared to just perform a direct lstat. I think there's definitely an opportunity for improvement there, though in time it'll be replaced by a swift-foundation package implementation instead. |
That seems surprising to me as well tbh. @hassila were you using the toolchain bundled with Xcode or one downloaded from swift.org? |
@neonichu I was testing with the Xcode 15b2 toolchain |
I made another measurement to give more exact information on sample source, this is on macOS 13.4.1 with Xcode 15b2:
Run time when sampling:
And sampling results: |
This process being sampled here doesn't appear to be using the URL resourceValue + .isSymlink API directly still. It's calling into NSFileAttributes code which does way more work than just the desired lstat.
|
Right, it's the out of the box tool chain from Xcode 15b2 as mentioned. I can try to build a version with the attached patch from the PR, but not sure what the point is - it's proven to help significantly? It seems this case is stuck between possible future foundation improvements vs. duplicating the code in this PR to get the performance issue addressed in a more timely manner? |
I think the idea is to use |
Yep! |
I think this commit should do that, don't have time right now to run any kind of comparison, but if anyone else on this thread is able to, that would be much appreciated. |
@neonichu I don't know if it's different for the Apple platforms implementation for If your suggested approach was used (rather than |
I gave it a spin with SPM main with TSC main built in release mode (changed SPM Package.swift to use a local copy of TSC) with your patch applied and without. This is on macOS / M1 Ultra.
Two runs without the patch gave:
with the patch applied:
As a reference, both are significantly slower than the proper Xcode release version that clocks in around 7 seconds for the same test, but it seems your patch gave a measurable improvement. Sample with the patch applied: |
And as a reference, with @pyrtsa original patch in this PR to get completely comparable numbers, I see:
|
Thank you so much for doing this @hassila! So it seems as if at least on macOS, doing what @kperryua suggested gives us the perf benefit without having to roll our own code here. On other platforms, we won't benefit because of how corelibs-foundation is implemented (as both @pyrtsa and @kperryua pointed out), but I don't think that should keep us from doing this to at least improve macOS performance. @tomerd wdyt? |
sgtm |
I lost track of this one, going to land my patch next week. |
This should provide a significant performance improvement on macOS. See [https://github.com/apple/swift-tools-support-core/pull/400#issuecomment-1618933610](this) for more discussion on non-macOS platforms. Co-authored-by: Pyry Jahkola <pyry.jahkola@iki.fi>
This should provide a significant performance improvement on macOS. See [this](swiftlang#400 (comment)]) for more discussion on non-macOS platforms. Co-authored-by: Pyry Jahkola <pyry.jahkola@iki.fi>
Closing in favor of #428 |
This should provide a significant performance improvement on macOS. See [this](swiftlang#400 (comment)]) for more discussion on non-macOS platforms. Co-authored-by: Pyry Jahkola <pyry.jahkola@iki.fi>
This should provide a significant performance improvement on macOS. See [this](#400 (comment)]) for more discussion on non-macOS platforms. Co-authored-by: Pyry Jahkola <pyry.jahkola@iki.fi>
Profiling what takes Xcode and SPM so long with some large repositories, the current
isSymlink
implementation stood out. (See link to Swift Forums post for details.)I was able to cut time in a third (in the given test case) by replacing it with the
lstat
call apple/swift-corelibs-foundation makes as part of itsFileManager.attributesOfItem(atPath:)
implementation.I have limited resources to take this work forward currently, cleaning up the implementation and adding Windows support, but leaving a PR here for comments so it's not lost.