-
Notifications
You must be signed in to change notification settings - Fork 36
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
change KindIdentifier into a struct to handle unknown symbol kinds #7
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@QuietMisdreavus I think it would be useful to document why we're keeping track of "unknown" kinds, e.g., why this information would be useful for clients.
Also, since the unknown kinds are tracked in a static context, that state would be shared across different parsing instances of symbol graphs. Do you see potential issues with that approach?
This could cause issues if multiple unrelated symbol graphs are handled in the same process, since there's no way to wipe out this cache without exiting the process entirely. An alternative would be to have this in a globally-accessible static cache, that each symbol graph would then fill and wipe out as needed, or that could allow users to manually clear it as desired. It would make logical sense to store this at the symbol graph level, but the isolation of the Decodable protocol conformance makes it difficult to relate a symbol kind to the symbol or graph it's appearing on (see SR-15570 which i filed yesterday). That said, i don't see an issue with this is Swift-DocC's access patterns persist, since it's likely that the set of symbol graphs being handled at the same time are related by language or API. (Any other consumer may run into the aforementioned issues, especially if they choose to adopt a "persistent process" model.) |
@swift-ci Please test |
I see the value in keeping track of the unknown kinds' string name in |
The static store isn't intended for client use; it's mainly to cut down on string allocations in situations where a large symbol graph has many of the same symbol kind that SymbolKit doesn't already parse. It's a performance optimization. So, in effect the problem i mentioned earlier isn't that bad, since it would cause that static cache to hang around longer than necessary and create some memory bloat of its own. I could wire this into swift-docc and run some memory comparisons with and without the cache; that way we can see how much of an "issue" it's actually resolving. |
Ah I see—in that case I'd be curious about the memory investigation as well, yes. I'd also be interested in seeing if there's a time performance hit, since accesses to the static cache are synchronized using a lock, which might be noticeable for clients that decode symbol graph files concurrently. |
I ran a few benchmarks on my machine using swift-docc's Between main and this branch:
Between the
Between this branch and the edited version without the static cache:
It looks like having the associated data in there is still adding a bit of a performance hit. The test bundle i used was generated by DocC's |
Could you please clarify the difference between "a simplified version without the static cache" and "the edited version without the static cache"? I'm not sure I understand the distinction. It's possible that adding an associated value to the enum is indeed incurring a performance penalty. By the way, I think another way to model unknown kinds would be to actually make public struct KindIdentifier: Equatable, Hashable, Codable {
private var identifier: String
public init(identifier: String) { … }
public static let `associatedtype`: Self = .init(identifier: "associatedtype")
…
} And we'd have a static property with all the cases that SymbolKit provides, if we need that. This is similar to how |
They're the same; apologies for the confusion. I'll update the branch to use the model that you proposed, and run some more performance tests with it. |
It looks like storing kind identifiers as a struct instead of an enum gives a slightly better result, though still a bit of a slowdown from
|
Can you make it clear why we have to update the swift-tools version into 5.5 and placing minimum-version requirements on macOS and iOS if we introduce the class? And it seems if we update the Package.swift version to 5.5, someone who build SymbolKit using a lower version will be broken. Can we just use the [email protected] file which is already merged by #6 |
If we're taking out the static cache entirely (which it seems like we might), i could remove that requirement. I'd put it in as a copy/paste from Swift-DocC, since the APIs it uses on macOS and iOS needed a certain OS version (and i assume the way it was specified, in the Package.swift, had a swift-tools requirement - i haven't verified that assumption, though). Since Franklin's on vacation for now, i'll update this PR with my most recent branch (refactoring |
Note that the changes in the most recent commit will break downstream code (now that there is no |
Second suggestion:
|
Also I suggest this change to be rebased onto #8, so that we can track the change more easily rather on a giant Symbol.swift file |
11d347c
to
aaadd9f
Compare
Sources/SymbolKit/SymbolGraph/Symbol/Symbol+KindIdentifier.swift
Outdated
Show resolved
Hide resolved
Sources/SymbolKit/SymbolGraph/Symbol/Symbol+KindIdentifier.swift
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Hello @QuietMisdreavus, is there any progress on this PR? |
case .module: return "module" | ||
case .unknown: return "unknown" | ||
} | ||
private init(rawIdentifier: String) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any value in making this public so clients can create new symbol kinds without updating SymbolKit itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it looks like we have a public initializer below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public initializer first checks against the known symbol kinds, then returns the original kind identifier string unchanged if it doesn't match any of the known ones. This at least can keep down on string allocations that are stored in the final symbol graph, if it uses known symbol kinds. In the end, it does defer to this rawIdentifier
initializer, either via a static property or by storing the unknown kind string.
e0999b2
to
e28aab7
Compare
I've rebased the PR to resolve the merge conflict (it was the addition of the @swift-ci Please test |
Resolves rdar://84276085
This PR changes the type definition of
KindIdentifier
from an enum into a struct with static fields for common values. This has two effects:KindIdentifier
now requires acase default
branch to handle unknown values, instead of simply matching on the.unknown
enum case.