Skip to content
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

Improve performance of module lookups #178

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 24 additions & 17 deletions Sources/Knit/Module/DependencyBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,42 @@ final class DependencyBuilder {

let toAssemble = assemblyCache.toAssemble

var inputLookup: [AssemblyReference: any ModuleAssembly] = [:]
for module in modules {
let ref = AssemblyReference(type(of: module))
inputLookup[ref] = module
for replaced in ref.type.replaces {
inputLookup[AssemblyReference(replaced)] = module
}
}

// Instantiate all types
for ref in toAssemble {
guard !self.isRegisteredInParent(ref) else {
continue
}
assemblies.append(try instantiate(moduleType: ref.type))
assemblies.append(try instantiate(moduleRef: ref, inputLookup: inputLookup))
}
}

private func instantiate(moduleType: any ModuleAssembly.Type) throws -> any ModuleAssembly {
let inputModule = inputModules.first(where: { type(of: $0) == moduleType})
let existingType = inputModules.first { assembly in
return type(of: assembly).doesReplace(type: moduleType)
}
if let existingType {
return existingType
private func instantiate(
moduleRef: AssemblyReference,
inputLookup: [AssemblyReference: any ModuleAssembly]
) throws -> any ModuleAssembly {
if let inputModule = inputLookup[moduleRef] {
return inputModule
}
if let overrideType = try defaultOverride(moduleType, fromInput: inputModule != nil),

if let overrideType = try defaultOverride(moduleRef.type, fromInput: false),
let autoInit = overrideType as? any AutoInitModuleAssembly.Type {
return autoInit.init()
}
if let inputModule {
return inputModule
}
if let autoInit = moduleType as? any AutoInitModuleAssembly.Type {

if let autoInit = moduleRef.type as? any AutoInitModuleAssembly.Type {
return autoInit.init()
}

throw DependencyBuilderError.moduleNotProvided(moduleType, dependencyTree.sourcePathString(moduleType: moduleType))
throw DependencyBuilderError.moduleNotProvided(
moduleRef.type,
dependencyTree.sourcePathString(moduleType: moduleRef.type)
)
}

private func gatherDependencies(
Expand Down
11 changes: 7 additions & 4 deletions Sources/Knit/Module/DependencyTree.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Foundation
public struct DependencyTree: CustomDebugStringConvertible {

// Assemblies that were originally provided to create the tree
private let inputModules: [AssemblyReference]
private let inputModules: Set<AssemblyReference>

// List of all registered modules
private var allModules: Set<AssemblyReference>
Expand All @@ -17,8 +17,8 @@ public struct DependencyTree: CustomDebugStringConvertible {
private var moduleSources: [AssemblyReference: AssemblyReference] = [:]

init(inputModules: [any ModuleAssembly]) {
self.inputModules = inputModules.map { AssemblyReference(type(of: $0)) }
allModules = Set(self.inputModules)
self.inputModules = Set(inputModules.map { AssemblyReference(type(of: $0)) })
allModules = self.inputModules
}

mutating func add(
Expand Down Expand Up @@ -48,7 +48,10 @@ public struct DependencyTree: CustomDebugStringConvertible {
}

public var debugDescription: String {
return inputModules.flatMap { debugDescription(assemblyRef: $0, indent: "") }.joined(separator: "\n")
let sortedInputs = inputModules
.map { ($0, $0.debugDescription) }
.sorted(by: {$0.1 < $1.1})
return sortedInputs.flatMap { debugDescription(assemblyRef: $0.0, indent: "") }.joined(separator: "\n")
}

public func dumpGraph() {
Expand Down
4 changes: 2 additions & 2 deletions Tests/KnitTests/DependencyBuilderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ final class DependencyBuilderTests: XCTestCase {
XCTAssertEqual(
builder.dependencyTree.debugDescription,
"""
Assembly3
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moving to a Set loses the input ordering for debug descriptions, it's now alphabetically ordered

Assembly1
- Assembly2
Assembly3
"""
)

Expand Down Expand Up @@ -71,9 +71,9 @@ final class DependencyBuilderTests: XCTestCase {
XCTAssertEqual(
builder.dependencyTree.debugDescription,
"""
Assembly1
Assembly4
- Assembly2
Assembly1
"""
)
}
Expand Down