Repository navigation
perf(python): read union case fields directly instead of rebuilding Array - #4725
Conversation
Python Type Checking Results (Pyright)
Excluded files with errors (4 files)These files have known type errors and are excluded from CI. Remove from
|
5a140d9 to
ec38a85
Compare
ReviewNice find and a solid, well-motivated fix — reading the named backing field directly instead of rebuilding an
Notes / risks
On
|
…typing.cast` (#4731) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
When working on Scriptorium, I discovered that Python generated code is slower than JS for union-heavy workloads.
One of the main reasons is that union case field reads (
x.fields[i], emitted for every pattern match) went throughUnion.fields, a@propertythat rebuilds a fullArrayfromgetattr()calls on every access. Even if JavaScript does a similar thing, in that case it storesfieldsonce at construction, while Python rebuilds it every time.In my codebase, it resulted in
union.fieldsbeing called (~8M calls) when profiling.Amounting to ~5sec of the run time.
Before:
After:
The drawback I found from this change is that we now need to cast the union to the case class type before reading its fields. Otherwise, Pyright will complain that the "field property" (ex
left_,item1, etc. ) is not defined on the union type.Benchmark
I made a small benchmark to test the performance difference between the two approaches using something like the following code:
Results: