Skip to content

Performance and Benchmarks

Liu.Yandong.Hanks edited this page Aug 20, 2026 · 4 revisions

性能与基准

Performance and Benchmarks

适用版本:4.0.0

Applies to 4.0.0.

首页 · 语言指南

Home · Language Guide

性能数据用于比较版本和发现回归,不是跨机器的承诺。部署前请在目标 CPU、运行时、宿主配置和真实脚本上重新测量。

Performance data is for comparing versions and detecting regressions, not a cross-machine guarantee. Remeasure on the target CPU, runtime, host configuration, and real scripts before deployment.

运行基准

Running Benchmarks

统一 Benchmark 项目位于 benchmark/,同时覆盖运行时热路径与编译 pipeline。

The unified benchmark project lives in benchmark/ and covers both runtime hot paths and the compiler pipeline.

# 快速冒烟检查
dotnet run --project benchmark/Benchmark.csproj -c Release -- --smoke

# 输出简易 CSV 对比
dotnet run --project benchmark/Benchmark.csproj -c Release -- --compare

# 运行完整 BenchmarkDotNet
dotnet run --project benchmark/Benchmark.csproj -c Release

Run the smoke check, simple CSV comparison, or the complete BenchmarkDotNet suite with the commands above.

重点覆盖 Domain 创建、空调用、函数调用、模块调用、闭包调用、对象、数组、HashMap、字符串、JSON、TDoc、Regex、CLR 互操作,以及 Lexer、Parser、Emitter、单模块/多模块编译与 CompileBlock

Coverage includes domain creation, empty calls, function calls, module calls, closure calls, objects, arrays, HashMap, strings, JSON, TDoc, Regex, CLR interop, and the lexer, parser, emitter, single-/multi-module compilation, and CompileBlock.

TDoc 基准包含原始值读写、普通嵌套对象读写、一般 ArrayInt32Array 与宽对象读取,用于跟踪解析热路径、普通对象写入和 Packed Array 的分配回归。

TDoc benchmarks cover primitive reads/writes, ordinary nested-object reads/writes, general Array, Int32Array, and wide-object reads to track parser hot paths, ordinary-object writing, and packed-array allocation regressions.

dotnet run --project benchmark/Benchmark.csproj -c Release -- --filter "*TypedDocument*"

TDoc 热路径基线

TDoc Hot-path Baseline

下列结果来自 2026-08-20 的 Release/net10.0 BenchmarkDotNet ShortRun。环境为 Windows 11、Intel Xeon W-2235、.NET SDK 10.0.400 与 Runtime .NET 10.0.11。ShortRun 用于回归对比,不应视为跨机器的绝对服务等级承诺。

The results below are from a Release/net10.0 BenchmarkDotNet ShortRun on 2026-08-20: Windows 11, Intel Xeon W-2235, .NET SDK 10.0.400, and Runtime .NET 10.0.11. ShortRun is for regression comparison, not an absolute cross-machine service-level guarantee.

指标 Mean Allocated 说明
SerializePrimitive 226.0 ns 32 B 结果字符串分配;无中间树
DeserializePrimitive 246.7 ns 0 B 流式扫描与直接绑定
SerializeNestedObject 1.289 µs 296 B 规范化文本与结果字符串
DeserializeNestedObject 2.410 µs 640 B 构造目标脚本对象
SerializePackedInt32Array1024 144.817 µs 20,360 B 文本结果为主要分配
DeserializePackedInt32Array1024 168.155 µs 4,192 B 目标 int[]/Packed Array
DeserializeGenericArray1024 178.815 µs 32,992 B 每个元素的通用 ScriptDatum 存储
DeserializeWideObject256 371.489 µs 16,608 B 256 个目标对象属性

The table records mean time and managed allocation. Primitive parsing stays allocation-free; object and array allocations shown here are the returned data or output text, not an intermediate syntax tree.

已记录的热路径结果

Recorded Hot-path Results

下列数据来自 2026-08-15 的 Release/net10.0 BenchmarkDotNet ShortRun。它们是文档基线;完整套件可用不带 --filter 的命令重建。

The following results are from a Release/net10.0 BenchmarkDotNet ShortRun on 2026-08-15. They are a documentation baseline; regenerate the full suite by running without --filter.

dotnet run --project benchmark/Benchmark.csproj -c Release -- \
  --filter "*FunctionCallLoop*" "*ModuleCallLoop*" "*NumericLoop*"
指标 规模 Mean Allocated 观察
NumericLoop 1,000 1.477 µs 0 B 数值 local 和算术保持为原生 CIL
NumericLoop 10,000 13.483 µs 0 B 时间线性增长,无循环内分配
FunctionCallLoop 1,000 82.668 µs 0 B 同模块数值调用使用原生 specialization
FunctionCallLoop 10,000 766.803 µs 0 B 调用帧复用,无逐次上下文分配
ModuleCallLoop 1,000 122.591 µs 0 B 跨模块通用调用边界零分配
ModuleCallLoop 10,000 1.186 ms 0 B 动态分发成本可控且无逐次分配

The table records means and allocations for the documented hot paths. All six cases measured zero managed allocations on the execution path.

测试环境为 BenchmarkDotNet 0.15.8、Windows 11 10.0.28000.2704、Intel Core i7-13700KF、.NET SDK 10.0.400、Runtime .NET 10.0.11ShortRun Job。Benchmark 复用预构造的宿主参数数组,因此 Allocated 只反映实际执行路径。

The environment was BenchmarkDotNet 0.15.8, Windows 11 10.0.28000.2704, Intel Core i7-13700KF, .NET SDK 10.0.400, Runtime .NET 10.0.11, and the ShortRun job. The benchmark reuses prebuilt host argument arrays, so Allocated reflects the actual execution path only.

写法建议

Writing Recommendations

  • 在热点循环中缓存 length、模块常量和重复属性读取。
  • 数值密集且长度已知时使用 Packed Array,而不是通用 Array
  • 使用 StringBuffer 构造大量文本,避免循环中的字符串反复拼接。
  • 只在真正需要模块持久化输出或调试符号时选择 Persistence;常规执行优先选择满足需求的较轻模式。
  • 优化前先测量,优化后同时运行功能测试和 benchmark。
  • Cache length, module constants, and repeated property reads inside hot loops.
  • Use packed arrays rather than general Array for known-length numeric work.
  • Use StringBuffer for substantial text construction instead of repeated string concatenation in a loop.
  • Choose Persistence only when durable module output or debugging symbols are truly required; otherwise use the lightest mode that meets the need.
  • Measure before optimizing, then run both functional tests and benchmarks afterward.

Clone this wiki locally