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 DependencyBuilder #226

Merged
merged 1 commit into from
Jan 15, 2025

Conversation

skorulis-ap
Copy link
Collaborator

@skorulis-ap skorulis-ap commented Dec 23, 2024

This removes the need for some casts like if ref.type is any AbstractAssembly.Type which it turns out have a heavy performance penalty in large apps.
This makes the code a little bit more complex but for a large app saves ~100ms in startup time.

@skorulis-ap skorulis-ap force-pushed the skorulis/cast-performance branch from c85f7c8 to 7307774 Compare December 23, 2024 09:12
@skorulis-ap skorulis-ap marked this pull request as ready for review January 6, 2025 23:20
@skorulis-ap skorulis-ap requested a review from bradfol January 6, 2025 23:20
@skorulis-ap skorulis-ap changed the title Experiment to improve performance of the dependency builder Improve performance of the dependency builder Jan 7, 2025
@skorulis-ap skorulis-ap changed the title Improve performance of the dependency builder Improve performance of DependencyBuilder Jan 7, 2025
Copy link
Collaborator

@bradfol bradfol left a comment

Choose a reason for hiding this comment

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

Thanks for this! 🙏

@@ -97,3 +120,12 @@ public struct OverrideBehavior {
return NSClassFromString("XCTestCase") != nil
}
}

public struct ModuleAssemblyFlags: OptionSet {
public let rawValue: Int
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
public let rawValue: Int
public let rawValue: UInt

@@ -40,6 +45,24 @@ public extension ModuleAssembly {
return self.resolverType == $0.resolverType
}
}

static var _assemblyFlags: [ModuleAssemblyFlags] {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
static var _assemblyFlags: [ModuleAssemblyFlags] {
static let _assemblyFlags: [ModuleAssemblyFlags] = {

Can we make this a computed static property so it is only calculated once per assembly type?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I can't add a static let in an extension

Comment on lines +51 to +54
if self is any AutoInitModuleAssembly.Type {
result.append(.autoInit)
}
if self is any AbstractAssembly.Type {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems like for these is checks we are just moving the call site? Is there some other way that this causes a performance improvement?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the fallback, it only gets hit if a code gen version isn't available.

Comment on lines +60 to +64
static func _autoInstantiate() -> (any ModuleAssembly)? {
if let autoInit = self as? any AutoInitModuleAssembly.Type {
return autoInit.init()
}
return nil
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
static func _autoInstantiate() -> (any ModuleAssembly)? {
if let autoInit = self as? any AutoInitModuleAssembly.Type {
return autoInit.init()
}
return nil
static func _autoInstantiate() -> (any ModuleAssembly)? {
return nil

Should we remove the as? check here and always return nil?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or alternately remove the default extension implementation entirely?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If I take out the default implementation then I'll have to add it manually for any test cases where it's not being autogenerated.

let isAutoInit: Bool
if config.assemblyType == .abstractAssembly {
accessorBlock = AccessorBlockSyntax(
accessors: .getter(.init(stringLiteral: "[.autoInit, .abstract]"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see this case covered in the unit tests currently, mind adding a test case for it?

@skorulis-ap skorulis-ap force-pushed the skorulis/cast-performance branch from 7307774 to ad7da66 Compare January 15, 2025 02:50
@skorulis-ap skorulis-ap force-pushed the skorulis/cast-performance branch from ad7da66 to 8c24c71 Compare January 15, 2025 02:56
@skorulis-ap skorulis-ap merged commit 6b852ec into main Jan 15, 2025
1 check passed
@skorulis-ap skorulis-ap deleted the skorulis/cast-performance branch January 15, 2025 03:14
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.

2 participants