I am working on a library where a dictionary-like data structure consumes instance property values using a list of key-paths. To use these key-paths as keys, I need to convert them into strings.
However, I noticed that using String(reflecting:) is roughly 295 times slower than assigning values using a hardcoded string subscript. When writing a large number of properties, this overhead accumulates into a noticeable millisecond-range delay.
If the overhead of using key-paths were, say, 5, 10, or even 20 times slower, it would be acceptable. However, a nearly 300-fold performance gap makes this API unacceptable for real-world production use.
Right now, the issue boils down to an unpleasant trade-off: either suffer from poor runtime performance or endure noticeably longer compilation times due to SwiftSyntax dependencies in macros.
Are there any ways to convert a KeyPath to a String in a faster way, other than using a macro that converts the property name into a string at compile-time?
Interesting question. From what I’ve found KeyPath doesn’t directly store property names and String(reflecting:) is mainly intended for debugging rather than retrieving names for program logic.
I wonder if caching the reflected strings could help when the same key paths are reused frequently. Another possibility might be a lightweight compile-time mapping that avoids bringing in the full SwiftSyntax dependency.
Curious to hear if anyone has explored alternative approaches, especially ones that balance runtime performance and compilation overhead ツ
Yes, this topic was brought up 1.5 years ago in this thread. However, at that time, plans to optimize KeyPath were also being discussed, as well as the possibility of using KeyPath to call functions, and some work may have been done on this topic.
Do you have any ideas on how to make something like this?