Skip to content

Conversation

RZhang05
Copy link
Contributor

@RZhang05 RZhang05 commented Oct 14, 2025

Closes #4273

Description

Re-use static to sema conversions from the compiler in the vm. Tried various changes in the linker to no success, tried caching static type ID calls, which was an improvement but affects execution, so not included.

              │ ./bbq/vm/test/old-3.txt │   ./bbq/vm/test/optimized-2.txt   │
              │         sec/op          │   sec/op     vs base              │
FTTransfer-14               39.10µ ± 2%   38.43µ ± 2%  -1.73% (p=0.007 n=8)

              │ ./bbq/vm/test/old-3.txt │ ./bbq/vm/test/optimized-2.txt │
              │          B/op           │     B/op      vs base         │
FTTransfer-14              36.93Ki ± 0%   36.93Ki ± 0%  ~ (p=0.660 n=8)

              │ ./bbq/vm/test/old-3.txt │ ./bbq/vm/test/optimized-2.txt │
              │        allocs/op        │ allocs/op   vs base           │
FTTransfer-14                965.0 ± 0%   965.0 ± 0%  ~ (p=1.000 n=8) ¹

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work
  • Code follows the standards mentioned here
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

@RZhang05 RZhang05 changed the title Reuse sema types from compiler, remove sema type in member access check. [Compiler] Re-use static to sema conversions in vm. Oct 14, 2025
Copy link

github-actions bot commented Oct 14, 2025

Benchstat comparison

  • Base branch: onflow:master
  • Base commit: 3ec0c24
Results

old.txtnew.txt
time/opdelta
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ContractFunctionInvocation-4405µs ± 0%401µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
ContractImport-4228µs ± 0%223µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ExportType/composite_type-4264ns ± 0%267ns ± 0%~(p=1.000 n=1+1)
ExportType/simple_type-477.9ns ± 0%78.0ns ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
FTTransfer-4122µs ± 0%123µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ImperativeFib-420.1µs ± 0%19.9µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
ImperativeFib-413.6µs ± 0%14.1µs ± 0%~(p=1.000 n=1+1)
ImperativeFibNewCompilerNewVM-435.0µs ± 0%35.2µs ± 0%~(p=1.000 n=1+1)
ImperativeFibNewVM-416.2µs ± 0%16.2µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
InterpretRecursionFib-42.03ms ± 0%2.05ms ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
InterpreterFTTransfer-4110µs ± 0%113µs ± 0%~(p=1.000 n=1+1)
InterpreterImperativeFib-420.5µs ± 0%20.1µs ± 0%~(p=1.000 n=1+1)
InterpreterNewStruct-463.6µs ± 0%62.3µs ± 0%~(p=1.000 n=1+1)
MethodCall/concrete_type_method_call-446.1µs ± 0%46.2µs ± 0%~(p=1.000 n=1+1)
MethodCall/interface_method_call-467.3µs ± 0%64.7µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
NewInterpreter/new_interpreter-41.04µs ± 0%1.03µs ± 0%~(p=1.000 n=1+1)
NewInterpreter/new_sub-interpreter-4324ns ± 0%318ns ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
NewResource-486.2µs ± 0%85.0µs ± 0%~(p=1.000 n=1+1)
NewStruct-434.2µs ± 0%34.7µs ± 0%~(p=1.000 n=1+1)
NewStructRaw-43.83µs ± 0%3.75µs ± 0%~(p=1.000 n=1+1)
RecursionFib-4764µs ± 0%801µs ± 0%~(p=1.000 n=1+1)
RuntimeFungibleTokenTransfer-4721µs ± 0%742µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
RuntimeFungibleTokenTransferInterpreter-4594µs ± 0%592µs ± 0%~(p=1.000 n=1+1)
RuntimeFungibleTokenTransferVM-4657µs ± 0%634µs ± 0%~(p=1.000 n=1+1)
RuntimeResourceDictionaryValues-42.68ms ± 0%2.67ms ± 0%~(p=1.000 n=1+1)
RuntimeResourceTracking-412.3ms ± 0%12.2ms ± 0%~(p=1.000 n=1+1)
RuntimeScriptNoop-415.0µs ± 0%14.6µs ± 0%~(p=1.000 n=1+1)
RuntimeVMInvokeContractImperativeFib-429.0µs ± 0%28.4µs ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ValueIsSubtypeOfSemaType-472.4ns ± 0%72.4ns ± 0%~(p=1.000 n=1+1)
 
alloc/opdelta
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ContractFunctionInvocation-4152kB ± 0%152kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
ContractImport-474.0kB ± 0%73.9kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ExportType/composite_type-4120B ± 0%120B ± 0%~(all equal)
ExportType/simple_type-40.00B 0.00B ~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
FTTransfer-437.8kB ± 0%37.8kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ImperativeFib-48.30kB ± 0%8.30kB ± 0%~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
ImperativeFib-41.94kB ± 0%1.94kB ± 0%~(all equal)
ImperativeFibNewCompilerNewVM-421.8kB ± 0%21.8kB ± 0%~(p=1.000 n=1+1)
ImperativeFibNewVM-44.66kB ± 0%4.33kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
InterpretRecursionFib-41.19MB ± 0%1.19MB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
InterpreterFTTransfer-437.6kB ± 0%37.6kB ± 0%~(p=1.000 n=1+1)
InterpreterImperativeFib-48.29kB ± 0%8.29kB ± 0%~(all equal)
InterpreterNewStruct-424.5kB ± 0%24.5kB ± 0%~(p=1.000 n=1+1)
MethodCall/concrete_type_method_call-46.94kB ± 0%6.94kB ± 0%~(all equal)
MethodCall/interface_method_call-414.5kB ± 0%13.7kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
NewInterpreter/new_interpreter-4976B ± 0%976B ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-4232B ± 0%232B ± 0%~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
NewResource-440.4kB ± 0%40.4kB ± 0%~(p=1.000 n=1+1)
NewStruct-410.4kB ± 0%10.3kB ± 0%~(p=1.000 n=1+1)
NewStructRaw-42.61kB ± 0%2.57kB ± 0%~(p=1.000 n=1+1)
RecursionFib-488.1kB ± 0%88.1kB ± 0%~(all equal)
RuntimeFungibleTokenTransfer-4231kB ± 0%232kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
RuntimeFungibleTokenTransferInterpreter-4155kB ± 0%155kB ± 0%~(p=1.000 n=1+1)
RuntimeFungibleTokenTransferVM-4174kB ± 0%173kB ± 0%~(p=1.000 n=1+1)
RuntimeResourceDictionaryValues-41.77MB ± 0%1.76MB ± 0%~(p=1.000 n=1+1)
RuntimeResourceTracking-49.26MB ± 0%9.26MB ± 0%~(p=1.000 n=1+1)
RuntimeScriptNoop-47.99kB ± 0%7.98kB ± 0%~(p=1.000 n=1+1)
RuntimeVMInvokeContractImperativeFib-410.3kB ± 0%9.9kB ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ValueIsSubtypeOfSemaType-448.0B ± 0%48.0B ± 0%~(all equal)
 
allocs/opdelta
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ContractFunctionInvocation-42.47k ± 0%2.47k ± 0%~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
ContractImport-4931 ± 0%931 ± 0%~(all equal)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
ExportType/composite_type-43.00 ± 0%3.00 ± 0%~(all equal)
ExportType/simple_type-40.00 0.00 ~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
FTTransfer-4965 ± 0%965 ± 0%~(all equal)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ImperativeFib-4176 ± 0%176 ± 0%~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
ImperativeFib-449.0 ± 0%49.0 ± 0%~(all equal)
ImperativeFibNewCompilerNewVM-4210 ± 0%210 ± 0%~(all equal)
ImperativeFibNewVM-486.0 ± 0%84.0 ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
InterpretRecursionFib-417.7k ± 0%17.7k ± 0%~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
InterpreterFTTransfer-4788 ± 0%788 ± 0%~(all equal)
InterpreterImperativeFib-4175 ± 0%175 ± 0%~(all equal)
InterpreterNewStruct-4418 ± 0%418 ± 0%~(all equal)
MethodCall/concrete_type_method_call-4135 ± 0%135 ± 0%~(all equal)
MethodCall/interface_method_call-4285 ± 0%275 ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
NewInterpreter/new_interpreter-415.0 ± 0%15.0 ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-44.00 ± 0%4.00 ± 0%~(all equal)
pkg:github.com/onflow/cadence/bbq/vm/test goos:linux goarch:amd64
NewResource-4735 ± 0%735 ± 0%~(all equal)
NewStruct-4219 ± 0%219 ± 0%~(all equal)
NewStructRaw-438.0 ± 0%38.0 ± 0%~(all equal)
RecursionFib-43.65k ± 0%3.65k ± 0%~(all equal)
RuntimeFungibleTokenTransfer-43.94k ± 0%3.94k ± 0%~(all equal)
pkg:github.com/onflow/cadence/runtime goos:linux goarch:amd64
RuntimeFungibleTokenTransferInterpreter-42.93k ± 0%2.93k ± 0%~(all equal)
RuntimeFungibleTokenTransferVM-43.06k ± 0%2.99k ± 0%~(p=1.000 n=1+1)
RuntimeResourceDictionaryValues-436.7k ± 0%36.7k ± 0%~(p=1.000 n=1+1)
RuntimeResourceTracking-4159k ± 0%159k ± 0%~(all equal)
RuntimeScriptNoop-4113 ± 0%113 ± 0%~(all equal)
RuntimeVMInvokeContractImperativeFib-4213 ± 0%207 ± 0%~(p=1.000 n=1+1)
pkg:github.com/onflow/cadence/interpreter goos:linux goarch:amd64
ValueIsSubtypeOfSemaType-41.00 ± 0%1.00 ± 0%~(all equal)
 

@RZhang05 RZhang05 self-assigned this Oct 14, 2025
@RZhang05 RZhang05 force-pushed the raymond/optimize-static-to-sema branch from 84d40f6 to d6167e7 Compare October 14, 2025 19:23
@RZhang05 RZhang05 force-pushed the raymond/optimize-static-to-sema branch from 22c2edb to 7bc4611 Compare October 15, 2025 19:30
@RZhang05 RZhang05 force-pushed the raymond/optimize-static-to-sema branch from 3c317a6 to b7fad6b Compare October 15, 2025 19:37
@RZhang05 RZhang05 marked this pull request as ready for review October 15, 2025 20:22
Copy link
Member

@SupunS SupunS left a comment

Choose a reason for hiding this comment

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

It's surprising how/why caching doesn't improve the performance, given that first iteration of caching in #4054 gave us some improvement.

Given that we already cache it after the very first conversion, maybe that initial conversion overhead is trivial?
Could you please add some more stat: for example, the number of cache hits/misses before and after the improvement?

Additionally, do we also need to cache types coming from the imports / for the imported programs?

Variables []Variable[E]
Types []T
Globals []Global
SemaTypeCache map[sema.TypeID]sema.Type
Copy link
Member

Choose a reason for hiding this comment

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

bbq.Program is currently serializable (and deserializable), even though we don't make use of it at the moment. But, we would lose this capability if we include sema.Type information in bbq.Program.

Could we instead pass this mapping externally? i.e: maybe as part of the vm.Config?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Compiler] Optimize conversion between static and sema types

2 participants