Skip to content

Commit 642f73f

Browse files
committed
more
1 parent 50f5025 commit 642f73f

21 files changed

Lines changed: 120 additions & 1505785 deletions

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
##### Enhancements
88

99
- Added support for Bazel 9.x.
10-
- Significant performance improvements. Total runtime scanning the Reddit iOS codebase reduced by 72.6% from 77.2s to 21.2s.
11-
- Significant performance improvements. Total runtime scanning the Reddit iOS codebase reduced by 74.6% from 77.2s to 19.6s.
10+
- Significant performance improvements. Total runtime scanning the Reddit iOS codebase reduced by 78.8% from 77.2s to 16.4s.
1211

1312
##### Bug Fixes
1413

Sources/Indexer/SwiftIndexer.swift

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,6 @@ final class SwiftIndexer: Indexer {
163163
/// phase two.
164164
func phaseOne() throws {
165165
var rawDeclsByKey: [RawDeclaration.Key: [(RawDeclaration, [RawRelation])]] = [:]
166-
// Array (not Set) to avoid redundant hashing -- deduplication happens
167-
// in SourceGraph.allReferences when references are added under the lock.
168166
var references: [Reference] = []
169167

170168
for unit in units {
@@ -246,11 +244,8 @@ final class SwiftIndexer: Indexer {
246244
}
247245

248246
try graph.withLock { graph in
249-
graph.ensureReferencesCapacity(graph.allReferences.count + references.count)
250247
graph.add(references)
251248
try graph.add(newDeclarations)
252-
// Apply batched retention after insertion so any synthetic
253-
// retained references resolve against the completed file graph.
254249
graph.markRetained(retainedDecls)
255250

256251
if retainAllDeclarations {
@@ -260,8 +255,6 @@ final class SwiftIndexer: Indexer {
260255

261256
establishDeclarationHierarchy()
262257

263-
// Only sort when needed -- associateDanglingReferences is the sole consumer
264-
// and it early-exits when there are no dangling references.
265258
if !danglingReferences.isEmpty {
266259
sortedDeclarationsCache = declarations.sorted()
267260
}
@@ -359,7 +352,6 @@ final class SwiftIndexer: Indexer {
359352
for (parent, decls) in childDeclsByParentUsr {
360353
guard let parentDecl = graph.declaration(withUsr: parent) else {
361354
if varParameterUsrs.contains(parent) {
362-
// These declarations are children of a parameter and are redundant.
363355
decls.forEach { graph.remove($0) }
364356
}
365357

@@ -370,7 +362,7 @@ final class SwiftIndexer: Indexer {
370362
decl.parent = parentDecl
371363
}
372364

373-
parentDecl.declarations.formUnion(decls)
365+
parentDecl.declarations.append(contentsOf: decls)
374366
}
375367
}
376368
}
@@ -513,17 +505,17 @@ final class SwiftIndexer: Indexer {
513505
graph.markCommandIgnored(decl, kind: kind)
514506
decl.unusedParameters.forEach { graph.markCommandIgnored($0, kind: kind) }
515507

516-
commandIgnoreUnsafe(Array(decl.declarations), kind: kind, graph: graph)
508+
commandIgnoreUnsafe(decl.declarations, kind: kind, graph: graph)
517509
}
518510
}
519511

520512
private func associateUnsafe(_ ref: Reference, with decl: Declaration) {
521513
ref.parent = decl
522514

523515
if ref.kind == .related {
524-
decl.related.insert(ref)
516+
decl.related.append(ref)
525517
} else {
526-
decl.references.insert(ref)
518+
decl.references.append(ref)
527519
}
528520
}
529521

@@ -561,7 +553,7 @@ final class SwiftIndexer: Indexer {
561553

562554
for param in params {
563555
let paramDecl = param.makeDeclaration(withParent: functionDecl, interner: self.graph.usrInterner)
564-
functionDecl.unusedParameters.insert(paramDecl)
556+
functionDecl.unusedParameters.append(paramDecl)
565557
try graph.add(paramDecl)
566558

567559
if retainAllDeclarations || (functionDecl.isObjcAccessible && configuration.retainObjcAccessible) {
@@ -643,7 +635,7 @@ final class SwiftIndexer: Indexer {
643635
location: decl.location
644636
)
645637
reference.parent = decl
646-
decl.related.insert(reference)
638+
decl.related.append(reference)
647639
references.append(reference)
648640
}
649641
}

Sources/PeripheryKit/ScanResult.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ public struct ScanResult {
55
enum Annotation {
66
case unused
77
case assignOnlyProperty
8-
case redundantProtocol(references: Set<Reference>, inherited: Set<String>)
8+
case redundantProtocol(references: [Reference], inherited: Set<String>)
99
case redundantPublicAccessibility(modules: Set<String>)
1010
case superfluousIgnoreCommand
1111
}

Sources/SourceGraph/Elements/Declaration.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,14 +306,14 @@ public final class Declaration {
306306
public let name: String
307307
public let usrs: Set<String>
308308
public let usrIDs: [USRID]
309-
public var unusedParameters: Set<Declaration> = []
310-
public var declarations: Set<Declaration> = []
309+
public var unusedParameters: [Declaration] = []
310+
public var declarations: [Declaration] = []
311311
public var commentCommands: Set<CommentCommand> = []
312-
public var references: Set<Reference> = []
312+
public var references: [Reference] = []
313313
public var declaredType: String?
314314
public var hasGenericFunctionReturnedMetatypeParameters: Bool = false
315315
public var parent: Declaration?
316-
public var related: Set<Reference> = []
316+
public var related: [Reference] = []
317317
public var isImplicit: Bool = false
318318
public var isObjcAccessible: Bool = false
319319
public internal(set) var isUsed: Bool = false
@@ -343,12 +343,12 @@ public final class Declaration {
343343
}
344344
}
345345

346-
public var immediateInheritedTypeReferences: Set<Reference> {
346+
public var immediateInheritedTypeReferences: [Reference] {
347347
let superclassReferences = related.filter { [.class, .struct, .protocol].contains($0.declarationKind) }
348348

349349
// Inherited typealiases are References instead of a Related.
350350
let typealiasReferences = references.filter { $0.declarationKind == .typealias }
351-
return superclassReferences.union(typealiasReferences)
351+
return superclassReferences + typealiasReferences
352352
}
353353

354354
public var isComplexProperty: Bool {

Sources/SourceGraph/Mutators/AncestralReferenceEliminator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ final class AncestralReferenceEliminator: SourceGraphMutator {
3131
}
3232
}
3333

34-
private func eliminateAncestralReferences(in references: Set<Reference>, stack: [USRID]) {
34+
private func eliminateAncestralReferences(in references: [Reference], stack: [USRID]) {
3535
for reference in references {
3636
if stack.contains(reference.usrID) {
3737
graph.remove(reference)

Sources/SourceGraph/Mutators/ExtensionReferenceBuilder.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ final class ExtensionReferenceBuilder: SourceGraphMutator {
2929
// Don't fold protocol extensions as they must be treated differently.
3030
guard kind != .extensionProtocol else { continue }
3131

32-
extendedDeclaration.declarations.formUnion(extensionDeclaration.declarations)
33-
extendedDeclaration.references.formUnion(extensionDeclaration.references)
34-
extendedDeclaration.related.formUnion(extensionDeclaration.related)
32+
extendedDeclaration.declarations.append(contentsOf: extensionDeclaration.declarations)
33+
extendedDeclaration.references.append(contentsOf: extensionDeclaration.references)
34+
extendedDeclaration.related.append(contentsOf: extensionDeclaration.related)
3535

3636
extensionDeclaration.declarations.forEach { $0.parent = extendedDeclaration }
3737
extensionDeclaration.references.forEach { $0.parent = extendedDeclaration }

Sources/SourceGraph/Mutators/InterfaceBuilderPropertyRetainer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ final class InterfaceBuilderPropertyRetainer {
3838
) {
3939
let inheritedDeclarations = graph.inheritedDeclarations(of: declaration)
4040
let descendentInheritedDeclarations = inheritedDeclarations.map(\.declarations).joined()
41-
let allDeclarations = declaration.declarations.union(descendentInheritedDeclarations)
41+
let allDeclarations = declaration.declarations + descendentInheritedDeclarations
4242

4343
for decl in allDeclarations {
4444
// Check IBOutlet properties

Sources/SourceGraph/Mutators/ProtocolConformanceReferenceBuilder.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,6 @@ final class ProtocolConformanceReferenceBuilder: SourceGraphMutator {
160160
}
161161

162162
// Apply all mutations after traversal completes.
163-
// Reserve capacity to reduce Set resizing during bulk insertions.
164-
let estimatedNewRefs = referencesToAdd.count + declarationsToRetain.count
165-
graph.ensureReferencesCapacity(graph.allReferences.count - referencesToRemove.count + estimatedNewRefs)
166-
167163
for reference in referencesToRemove {
168164
graph.remove(reference)
169165
}

Sources/SourceGraph/Mutators/RedundantProtocolMarker.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ final class RedundantProtocolMarker: SourceGraphMutator {
5959

6060
if areAllReferencesConformances {
6161
// The protocol is redundant.
62-
let inherited = graph.inheritedTypeReferences(of: protocolDecl).filter { $0.declarationKind == .protocol }
62+
let inherited = Array(graph.inheritedTypeReferences(of: protocolDecl).filter { $0.declarationKind == .protocol })
6363
graph.markRedundantProtocol(protocolDecl, references: protocolReferences, inherited: inherited)
6464
protocolDecl.declarations.forEach { graph.markIgnored($0) }
6565
}

Sources/SourceGraph/Mutators/UnusedImportMarker.swift

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@ final class UnusedImportMarker: SourceGraphMutator {
3636
func mutate() throws {
3737
guard !configuration.disableUnusedImportAnalysis else { return }
3838

39+
let files = graph.indexedSourceFiles
40+
3941
// Pre-intern all module names (source file modules, import statements,
4042
// retained modules) so that wordCount is stable for all bitsets.
41-
for file in graph.indexedSourceFiles {
43+
var fileToIndex = [ObjectIdentifier: Int](minimumCapacity: files.count)
44+
for (i, file) in files.enumerated() {
45+
fileToIndex[ObjectIdentifier(file)] = i
4246
for name in file.modules {
4347
_ = graph.moduleInterner.intern(name)
4448
}
@@ -54,12 +58,6 @@ final class UnusedImportMarker: SourceGraphMutator {
5458
emptyBitset = ModuleBitset(wordCount: wordCount)
5559
let retainedModuleIDs = graph.moduleInterner.internBitset(retainedModules, wordCount: wordCount)
5660

57-
let files = graph.indexedSourceFiles
58-
var fileToIndex = [ObjectIdentifier: Int](minimumCapacity: files.count)
59-
for (i, file) in files.enumerated() {
60-
fileToIndex[ObjectIdentifier(file)] = i
61-
}
62-
6361
// Manual pointer instead of [UInt64] to eliminate bounds checking and
6462
// copy-on-write overhead in the inner loops that accumulate module bits.
6563
let totalWords = files.count * wordCount
@@ -209,26 +207,26 @@ final class UnusedImportMarker: SourceGraphMutator {
209207
let references: Set<Reference>
210208

211209
if decl.kind.isVariableKind {
212-
references = decl.references.filter { $0.role == .varType }
210+
references = Set(decl.references.filter { $0.role == .varType })
213211
} else if decl.kind == .enumelement {
214-
references = decl.references
212+
references = Set(decl.references)
215213
} else if decl.kind == .typealias {
216214
let transitiveReferences = decl.references.flatMapSet { ref -> Set<Reference> in
217215
guard let refDecl = graph.declaration(withUsrID: ref.usrID) else { return [] }
218216

219217
return referencedTypes(from: refDecl)
220218
}
221-
references = decl.references.union(transitiveReferences)
219+
references = Set(decl.references).union(transitiveReferences)
222220
} else if decl.kind.isFunctionKind {
223-
references = decl.references
221+
references = Set(decl.references
224222
.filter {
225223
[
226224
.returnType,
227225
.parameterType,
228226
].contains($0.role)
229-
}
227+
})
230228
} else if decl.kind == .protocol {
231-
references = decl.related.filter { $0.role == .refinedProtocolType }
229+
references = Set(decl.related.filter { $0.role == .refinedProtocolType })
232230
} else {
233231
references = []
234232
}

0 commit comments

Comments
 (0)