Skip to content

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented Sep 14, 2025

Since the indexing performance of most projects is bound by target preparation instead of actual indexing right now, I wasn’t able to measure any performance benefits of this. But it seems like a good thing to add regardless, because it might save CPU cycles.

Fixes #1268

@ahoppen
Copy link
Member Author

ahoppen commented Sep 14, 2025

@swift-ci Please test

Comment on lines +284 to +286
// the batch can be indexed by a single compiler invocation. However, we might discover that two Swift files within
// the same target have different build settings in the build server. In that case, the best thing we can do is
// trigger two compiler invocations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would this happen 🤔? For C-family, sure. But I would expect all files within a target to have the same build settings for Swift.

It's super unfortunate we have to look through the arguments to find -index-unit-output-path for every settings per file, even though they should all be the same for every batch (except for the output path).

Copy link
Member Author

@ahoppen ahoppen Sep 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don’t control what the BSP server gives us for the build settings, so a BSP server may return different build settings for different Swift files within the same target. It wouldn’t make much sense from a build server’s perspective in practice but I’ve learned that it’s better to design SourceKit-LSP in a way that makes as few implicit assumptions about the BSP server responses as possible and assuming that all Swift files within the same target have the same build settings would be one of them.

It's super unfortunate we have to look through the arguments to find -index-unit-output-path for every settings per file, even though they should all be the same for every batch (except for the output path).

Do you think from a performance perspective. If we launch a compiler to index the file, I doubt that scanning for a command line argument makes much of a difference. And really, we should be getting the output path from the buildTarget/sources response (fileInfo.outputPath), in which case the extraction of -index-unit-output-path is just a validity check to ensure the two match.

Comment on lines +702 to +700
// Since Swift files within the same target should build a single module, it is reasonable to assume that they all
// share the same build settings.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I'd even call this an assumption TBH - if it wasn't the case, things would be very broken.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reply as #2293 (comment). I guess it’s just nice to see that SourceKit-LSP continues to function even if the build server gives us unreasonable responses.

// hard to quanify the performance characteristics of different batch sizes. 5 seems like a good trade-off to
// share work between files within the same target without overloading a single job with too many files and
// thus loosing parallelism.
files.partition(intoBatchesOfSize: 5).map { (targetAndLanguage.target, targetAndLanguage.language, $0) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could make configurable? What's the driver choose for its batch sizes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to check with the driver. It schedules as many concurrent batches as the machine has CPU cores but limits the batch size to 25 (https://github.com/swiftlang/swift-driver/blob/main/Sources/SwiftDriver/Jobs/Planning.swift#L917-L1022). I think copying that behavior is as reasonable an ideas as I have. But I’d prefer to do that in a follow-up PR to keep this one focused on the actual implementation of batch indexing instead of introducing complications due to configuration options.

let newTask = Task<Bool, Never> { () -> Bool in
#if compiler(>=6.4)
#warning(
"Once we no longer Swift 6.2 toolchains, we can assume that the compiler has https://github.com/swiftlang/swift-driver/pull/1979"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Once we no longer Swift 6.2 toolchains, we can assume that the compiler has https://github.com/swiftlang/swift-driver/pull/1979"
"Once we no longer support Swift 6.3 toolchains, we can assume that the compiler has https://github.com/swiftlang/swift-driver/pull/1979"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the time that we stop supporting 6.2 we don’t need to worry about the early Swift 6.3 toolchain snapshots that didn’t have multi-file indexing support anymore.

…files

We should not take the number of files in an `UpdateIndexStoreTaskDescription` as an indication on how important the task is. If we do need this functionality, eg. because we want to update the index of files with syntactic matches for a rename term, this should be communicated using a specific purpose similar to `TargetPreparationPurpose`. Since the only reason we update the index store for a file right now is background indexing, such a check is not needed.
@ahoppen ahoppen force-pushed the multi-file-indexing branch from 231214d to d1981de Compare September 20, 2025 14:26
@ahoppen
Copy link
Member Author

ahoppen commented Sep 20, 2025

@swift-ci Please test

@ahoppen
Copy link
Member Author

ahoppen commented Sep 20, 2025

@swift-ci Please test Windows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support indexing of multiple files in a single swift-frontend invocation
2 participants