Skip to content

Commit 77fffad

Browse files
committed
Improve the performance of ProtocolConformanceReferenceBuilder through parallelism
1 parent 2d9b99a commit 77fffad

File tree

3 files changed

+33
-9
lines changed

3 files changed

+33
-9
lines changed

Sources/Indexer/SourceFileCollector.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Logger
44
import SourceGraph
55
import SwiftIndexStore
66
import SystemPackage
7+
import Shared
78

89
public struct SourceFileCollector {
910
private let indexStorePaths: Set<FilePath>

Sources/Indexer/JobPool.swift renamed to Sources/Shared/JobPool.swift

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import Foundation
2-
import Shared
32

4-
struct JobPool<Job> {
3+
public struct JobPool<Job> {
54
let jobs: [Job]
65

7-
func forEach(_ block: @escaping (Job) throws -> Void) throws {
6+
public init(jobs: [Job]) {
7+
self.jobs = jobs
8+
}
9+
10+
public func forEach(_ block: @escaping (Job) throws -> Void) throws {
811
var error: Error?
912

1013
DispatchQueue.concurrentPerform(iterations: jobs.count) { idx in
@@ -23,7 +26,8 @@ struct JobPool<Job> {
2326
}
2427
}
2528

26-
func flatMap<Result>(_ block: @escaping (Job) throws -> [Result]) throws -> [Result] {
29+
/// Throwing variant
30+
public func flatMap<Result>(_ block: @escaping (Job) throws -> [Result]) throws -> [Result] {
2731
var error: Error?
2832
var results: [Result] = []
2933
let lock = UnfairLock()
@@ -49,4 +53,21 @@ struct JobPool<Job> {
4953

5054
return results
5155
}
56+
57+
/// Non-throwing variant
58+
public func flatMap<Result>(_ block: @escaping (Job) -> [Result]) -> [Result] {
59+
var results: [Result] = []
60+
let lock = UnfairLock()
61+
62+
DispatchQueue.concurrentPerform(iterations: jobs.count) { idx in
63+
let job = jobs[idx]
64+
let result = block(job)
65+
66+
lock.perform {
67+
results.append(contentsOf: result)
68+
}
69+
}
70+
71+
return results
72+
}
5273
}

Sources/SourceGraph/Mutators/ProtocolConformanceReferenceBuilder.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ final class ProtocolConformanceReferenceBuilder: SourceGraphMutator {
1919
// MARK: - Private
2020

2121
private func referenceConformingDeclarationsImplementedInSuperclass() -> Set<Reference> {
22-
var newReferences: Set<Reference> = []
2322
let protocols = graph.declarations(ofKind: .protocol)
2423

25-
for proto in protocols {
24+
let newReferences = Set(JobPool(jobs: Array(protocols)).flatMap { [graph] proto in
25+
var result: [Reference] = []
2626
// Find all classes that implement this protocol.
2727
let conformingClasses = graph.references(to: proto)
2828
.reduce(into: Set<Declaration>()) { result, ref in
@@ -66,14 +66,16 @@ final class ProtocolConformanceReferenceBuilder: SourceGraphMutator {
6666
)
6767
reference.name = declInSuperclass.name
6868
reference.parent = unimplementedProtoDecl
69-
graph.add(reference, from: unimplementedProtoDecl)
70-
newReferences.insert(reference)
69+
result.append(reference)
7170
}
7271
}
7372
}
7473
}
7574
}
76-
}
75+
return result
76+
})
77+
// Perform mutations on the graph based on the calculated references
78+
newReferences.forEach { graph.add($0, from: $0.parent!) }
7779

7880
return newReferences
7981
}

0 commit comments

Comments
 (0)