sgcPivotGrid 基准测试

sgcPivotGrid 引擎 TsgcPivotEngine 在 1,000,000 行和 10,000,000 行数据上的实测时间:加载数据、以单次遍历和并行计算重新计算三种透视布局,以及引擎在数据之外增加的内存。每个数字都来自 sgcUI 演示中的基准测试程序,因此您可以在自己的硬件上运行同样的测试。

13.9 ms
重新计算 1,000,000 行,Sum,单次遍历
121.1 ms
重新计算 10,000,000 行,Sum,单次遍历
46.9 ms
10,000,000 行,Sum,4 线程并行计算
1,384.0 ms
使用 AppendRow 加载 10,000,000 行

Win64,Delphi 13,1 次预热运行后取 5 次运行的中位数,在下文所述的测试机器上测得。跳转到 Win64 结果、Win32 结果、QA 预算或如何自己运行测试。

测量内容

数据行由固定的随机种子生成,因此每台机器计算的透视结果都相同。每种模式都会检查 P1 的总计是否等于数值列之和。

场景程序的操作
加载用 AppendRow 加载 1,000,000 或 10,000,000 行,每行包含 3 个文本值、1 个数字和 1 个日期。文本在到达时被编码为成员索引。第二步通过 Store.SetFloat 为一个数字列填入 100,000 个不同的值。
P1 Sum2 个行字段(50 个地区乘以 20 个产品,加上小计和总计共 1,051 个行项)和 1 个列字段(12 个月),对一个值求 Sum。最基本的透视。
P3 CountDistinctP1 布局,统计具有 100,000 个不同值的列的不同值个数,这是最耗时的标准聚合。
P4 StdDev, Average, Max在 P1 布局上同时计算三个度量。
单次遍历默认引擎,ParallelCalculation 关闭。
1 至 14 线程设置 MaxThreads 并令 ParallelCalculation := True 和 ParallelThreshold := 1,因此 1,000,000 行也会并行运行。“所有 CPU”即 MaxThreads := 0,每个逻辑 CPU 一个线程,测试机器上为 14 个。
引擎内存引擎在已加载数据之外为 P1 分配的内存(QA 关卡 M1)。存储内存是已加载数据本身。

测试机器

一台带有正常桌面负载的开发工作站,而不是隔离的实验室机器。测量日期为 2026 年 11 月 4 日。

项目值
CPUIntel Core Ultra 5 245T,35 W 桌面处理器
核心6 个性能核心和 8 个能效核心,14 个逻辑 CPU
内存31.5 GB
操作系统Windows 11 Pro 26H2 (build 26300)
编译器Delphi 13 Florence,发布版本:开启优化,关闭范围检查和溢出检查
平台Win64(1 次预热运行后取 5 次运行的中位数)和 Win32(快速运行:1 次预热运行后 1 次计时运行)
sgcPivotGrid2026.11.0 Registered

该处理器混合了高性能核心和能效核心,每个工作线程运行在哪个核心由 Windows 决定。使用 8 个或更多线程时,部分工作会落在能效核心上:Win64 下 1,000,000 行的 P4 会在约 13 ms 和约 32 ms 之间交替,因此 8 线程时其中位数跳到 31.2 ms。

Win64

1 次预热运行后取 5 次运行的中位数。时间单位为毫秒。

加载与内存1,000,000 行10,000,000 行
AppendRow,3 个文本列、1 个浮点列、1 个日期列132.9 ms1,384.0 ms
Store.SetFloat,1 个具有 100,000 个不同值的浮点列8.6 ms98.3 ms
存储内存(6 列)36.0 MB576.0 MB
P1 之后的引擎内存,所有模式4.8 MB39.1 MB

重新计算,1,000,000 行

模式线程P1 SumP3 CountDistinctP4 StdDev, Average, Max
单次遍历113.9 ms25.6 ms26.3 ms
并行,1 线程112.2 ms21.6 ms26.3 ms
并行,2 线程29.6 ms18.2 ms17.8 ms
并行,4 线程47.1 ms15.9 ms12.9 ms
并行,8 线程86.8 ms15.3 ms31.2 ms
并行,所有 CPU146.8 ms16.5 ms31.8 ms

重新计算,10,000,000 行

模式线程P1 SumP3 CountDistinctP4 StdDev, Average, Max
单次遍历1121.1 ms300.2 ms216.9 ms
并行,1 线程1106.4 ms253.0 ms230.6 ms
并行,2 线程267.1 ms212.7 ms130.3 ms
并行,4 线程446.9 ms184.6 ms127.5 ms
并行,8 线程863.6 ms181.1 ms111.9 ms
并行,所有 CPU1473.5 ms186.4 ms105.4 ms

Win32

快速运行:1 次预热运行后 1 次计时运行,因此这些数字比 Win64 的中位数噪声更大。该程序支持大地址空间(large address aware),这是 10,000,000 行存储所必需的。

加载与内存1,000,000 行10,000,000 行
AppendRow,3 个文本列、1 个浮点列、1 个日期列143.7 ms1,511.9 ms
Store.SetFloat,1 个具有 100,000 个不同值的浮点列16.8 ms183.7 ms
存储内存(6 列)36.0 MB576.0 MB
P1 之后的引擎内存,所有模式4.7 MB39.1 MB

重新计算,1,000,000 行

模式线程P1 SumP3 CountDistinctP4 StdDev, Average, Max
单次遍历116.9 ms27.3 ms50.8 ms
并行,1 线程116.7 ms22.9 ms51.0 ms
并行,2 线程211.3 ms20.4 ms32.8 ms
并行,4 线程48.6 ms16.3 ms23.1 ms
并行,8 线程88.5 ms16.3 ms19.2 ms
并行,所有 CPU148.5 ms15.6 ms19.2 ms

重新计算,10,000,000 行

模式线程P1 SumP3 CountDistinctP4 StdDev, Average, Max
单次遍历1143.6 ms286.8 ms442.6 ms
并行,1 线程1139.4 ms253.6 ms463.7 ms
并行,2 线程288.0 ms207.8 ms252.4 ms
并行,4 线程452.5 ms176.8 ms141.7 ms
并行,8 线程857.2 ms167.1 ms159.6 ms
并行,所有 CPU1464.4 ms172.0 ms131.9 ms

.NET x64

基准测试程序的 .NET 移植版,使用与 Delphi 程序相同的数据行、布局和模式。它运行在另一个运行时上,因此请将这些数字视为独立的表格。1 次预热运行后取 5 次运行的中位数。时间单位为毫秒。

加载与内存1,000,000 行10,000,000 行
AppendRow,3 个文本列、1 个浮点列、1 个日期列75.6 ms770.4 ms
Store.SetFloat,1 个具有 100,000 个不同值的浮点列2.9 ms43.0 ms
存储内存(6 列)36.0 MB576.0 MB
P1 之后的引擎内存,所有模式4.7 MB39.1 MB

运行时:.NET 8.0.31,x64 进程,发布版本,使用 sgcPivotGrid 2026.11.0 Registered 的 net8.0 控制台程序,在上述测试机器上于同一天测得。内存是存活的托管堆,在完整回收之后用 GC.GetTotalMemory(true) 测得。

重新计算,1,000,000 行

模式线程P1 SumP3 CountDistinctP4 StdDev, Average, Max
单次遍历111.9 ms23.3 ms14.7 ms
并行,1 线程112.1 ms21.3 ms20.1 ms
并行,2 线程28.5 ms15.5 ms12.6 ms
并行,4 线程46.3 ms14.8 ms9.9 ms
并行,8 线程86.8 ms13.6 ms9.8 ms
并行,所有 CPU146.6 ms13.3 ms9.6 ms

重新计算,10,000,000 行

模式线程P1 SumP3 CountDistinctP4 StdDev, Average, Max
单次遍历167.6 ms275.1 ms128.0 ms
并行,1 线程176.4 ms215.0 ms175.9 ms
并行,2 线程244.2 ms159.6 ms89.9 ms
并行,4 线程428.8 ms133.7 ms56.2 ms
并行,8 线程834.0 ms151.7 ms72.6 ms
并行,所有 CPU1428.3 ms154.9 ms66.0 ms

.NET 的 QA 性能测试使用 Delphi 预算的 1.2 倍(x64 下 P1 为 120 ms)。本次运行中 1,000,000 行的每个关卡都在预算之内,并且在每种模式下 P1 的总计都等于各值之和。

运行 .NET 基准测试

  1. 从 sgcUI .NET 演示中打开 PivotGrid\Benchmark\Benchmark.csproj。该文件夹中的 README.md 有详细说明。
  2. 使用 .NET 8 SDK 或更高版本以 Release 配置生成并运行。并行计算模式需要 Registered 或 Trial 版本。
  3. 开关与 Delphi 程序的开关相同。每次运行都会写出 dotnet-<arch>.md、.json 和 .csv,例如 dotnet-x64.md。
dotnet run -c Release
dotnet run -c Release -- --rows=1m,10m --quick
dotnet run -c Release -- --rows=500k,2m --threads=4 --out=C:\bench

1,000,000 行的 QA 预算

QA 性能组在每次生成时都会在 Win64 和 Win32 上断言这些预算,任何一项未达标,QA 运行即告失败。10,000,000 行没有预算,QA 只报告其结果。

关卡测量内容Win64 预算Win64 实测Win32 预算Win32 实测
P1重新计算 1,000,000 行,2 个行字段,1 个列字段,1 个 Sum100 ms13.9 ms160 ms16.9 ms
P1P启用 ParallelCalculation 的 P1,每个 CPU 一个线程100 ms6.8 ms160 ms8.5 ms
P2用 AppendRow 加载 1,000,000 行,每行 3 个文本值、1 个浮点值和 1 个日期值,包含编码900 ms132.9 ms1,400 ms143.7 ms
P3P1 布局,对具有 100,000 个不同值的列做 CountDistinct400 ms25.6 ms600 ms27.3 ms
P4P1 布局,计算 StdDev、Average 和 Max180 ms26.3 ms280 ms50.8 ms
M1P1 在存储之上的引擎内存32 MB4.8 MB32 MB4.7 MB
M1P启用 ParallelCalculation 的 M1,每个 CPU 一个线程32 MB4.8 MB32 MB4.7 MB

这些预算被有意设得较为宽松,以便在较慢的生成机器上捕获性能回退。在测试机器上,实测值比预算低 5.5 到 22 倍。

并行计算

表中并行行增加了什么,以及应使用多少线程。Registered

ParallelCalculation := True 会把大规模重新计算拆分为 131,072 行的固定块,在工作线程上计算这些块,并按块顺序合并。MaxThreads 限制工作线程数(0 表示每个 CPU 一个,最多 64 个),ParallelThreshold 默认为 1,000,000 行,使更小的存储继续使用单次遍历。它默认关闭,因为 Sum、Average、Product 以及 StdDev 系列的结果可能在最后几位上与单次遍历不同。它包含在 Registered 和 Trial 版本中。

  • 将 MaxThreads 设为 4 到 8。在测试机器上,4 线程在 Win64 的两种规模下都给出最佳的 P1:1,000,000 行为 7.1 ms,10,000,000 行为 46.9 ms,而单次遍历分别为 13.9 ms 和 121.1 ms。
  • 线程越多不一定越快。1,000,000 行只有 8 个块,因此线程启动和合并的开销超过了节省的工作量。在 10,000,000 行时,14 线程的 P1 为 73.5 ms,而 4 线程为 46.9 ms,因为按顺序的合并是串行运行的。
  • 更重的度量扩展得更远。Win64 下 10,000,000 行的 P4 在 14 线程之前持续改善:105.4 ms,而单次遍历为 216.9 ms。
  • CountDistinct 获益最少。其不同值的计数是串行运行的,因此 P3 最多只快约 1.6 倍。

自己运行基准测试

在您自己的硬件上使用相同的程序、相同的数据行和相同的布局。

  1. 从 sgcUI 演示中打开 Demos\PivotGrid\Delphi\Benchmark\sgcPivotGridBenchmark.dpr。该文件夹中的 README.txt 有详细说明。
  2. 以发布版本为 Win64 或 Win32 生成,开启优化,关闭范围检查和溢出检查。并行计算模式需要 Registered 或 Trial 版本。
  3. 从控制台运行。默认值为 1,000,000 行和 10,000,000 行,线程数为 1、2、4、8 和所有 CPU。
sgcPivotGridBenchmark [--rows=1m,10m] [--threads=1,2,4,8,0] [--out=folder] [--quick]

sgcPivotGridBenchmark
sgcPivotGridBenchmark --rows=1m,10m --quick
sgcPivotGridBenchmark --rows=500k,2m --threads=4 --out=C:\bench
开关含义
--rows要测试的行数,可使用 k 和 m 后缀。
--threads并行模式的 MaxThreads 值。0 或 all 表示每个 CPU 一个线程。单次遍历始终运行。
--out输出文件夹,默认为可执行文件旁边的 benchmark 文件夹。
--quick预热之后只做 1 次计时运行,而不是取 5 次的中位数。

每次运行都会写出 delphi-<platform>.md、.json 和 .csv,其中包含机器、设置和每一项计时,并检查 1,000,000 行的 QA 预算。BenchmarkMain.pas 包含全部逻辑,因此您可以用自己的数据替换生成的数据行,并保留相同的计时和报告。如果您的数字与这些相差很大,请告诉我们。

请谨慎解读这些数字

  • 只有一台机器。挂钟时间会随 CPU(核心数、混合调度、睿频)、内存速度以及机器上的其他负载而变化。
  • 数据形态很重要:更多的成员、更多的不同值或更多的度量,比这里测量的布局花费更多的时间和内存。
  • Win32 的数字来自只有 1 次计时运行的快速运行。Win64 的数字是 5 次运行的中位数。
  • 本页不将 sgcPivotGrid 与其他透视组件比较。它只发布 sgcPivotGrid 的数字,所用方法任何人都可以重复。

QA 预算也记录在架构帮助主题中。

超值之选:All-AccesseSeGeCe 全部产品,含高级支持,每年 €1,059 起。
查看 All-Access 价格

使用 sgcPivotGrid 构建

下载 sgcUI 试用版,把 sgcPivotGrid 添加到您的 Delphi、C++ Builder 或 .NET 应用程序中。