性能基准¶
阅读性能结果时,需要同时核对代码版本、依赖、硬件、数据规模、参数和测量方法。
此前部分结果缺少完整运行环境,因此不再作为 0.0.24 的正式性能结论展示。
规则审计、完整相关性关系、宽表公共入口,以及新进程加载并查询报告的独立验收见 核心规模与报告消费验收。这些验收使用统一 CLI,每轮独立运行, 检查 RSS 预算和查询是否返回有效证据。结果与下方历史记录分开保存,原有规则发布门禁继续适用。
复现命令¶
完整分析链路(本地测量)¶
benchmarks/benchmark_analysis.py 复用既有宽表生成器和 RSS sampler,使用固定随机种子。
每次 CLI 调用启动独立进程。用 --source 指向优化前的 src 快照后,可以让两侧使用同一脚本、工作负载和线程配置。
将结果写入临时目录,例如在 PowerShell 中运行:
conda run -n mars python benchmarks/benchmark_analysis.py --rows 50000 --features 1001 --threads 4 --batch-size 50 --benchmark --output "$env:TEMP/analysis.json"
conda run -n mars python benchmarks/benchmark_analysis.py --stage profile --rows 50000 --features 1001 --threads 4 --batch-size 50 --output "$env:TEMP/profile.json"
记录环境:2026-09-30 至 2026-10-01(Asia/Shanghai),Windows 11 10.0.26200,Intel x64
Family 6 Model 183 Stepping 1,24 logical CPUs,Python 3.10.19、Polars 1.37.1、MARS 0.0.28,
固定 4 个 Polars 线程。优化前为 d3201a2 的 src 快照,优化后为本次未提交工作树。
随机种子为 2026。输入包含 50,000 行、1,001 个 Float32 特征,最后一批不足 50 个特征;
数据含 NaN、特殊值 -999、4 个分组、样本权重和金额。分箱场景以前 25,000 行作为显式基准,拟合 8 个箱,RC 使用默认的 total。
画像场景在独立进程中运行 missing/zeros/unique/mode/mean/std/min/max,不生成 sparkline。
两侧各 3 个独立进程,中位数如下(MiB = 1024² bytes):
| 测量 | 优化前 | 优化后 |
|---|---|---|
| 完整分箱评估耗时 | 11.53 s | 11.34 s |
| 分箱评估计算阶段峰值 RSS | 1907.7 MiB | 959.9 MiB |
| 输入准备后分箱评估峰值 RSS 增量 | 1484.4 MiB | 536.9 MiB |
| 独立画像耗时 | 3.38 s | 2.61 s |
| 独立画像计算阶段峰值 RSS | 498.1 MiB | 498.4 MiB |
| 输入准备后画像峰值 RSS 增量 | 75.0 MiB | 75.5 MiB |
评估各阶段中位数:
| 阶段 | 优化前 | 优化后 |
|---|---|---|
| 拟合与拟合诊断 | 6.163 s | 5.919 s |
| 当前及基准转换 | 1.263 s | 1.177 s |
| 当前样本聚合 | 1.812 s | 1.860 s |
| 基准分布 | 1.927 s | 1.953 s |
| 指标计算 | 0.074 s | 0.077 s |
| 报告表构造 | 0.209 s | 0.194 s |
阶段耗时不含所有输入预处理、对象装配和采样开销,不能直接相加等同总耗时。 分箱评估减少了全量分箱宽表和显式基准长表的内存占用,计算阶段的峰值 RSS 约减半。 耗时变化小于轮间波动,因此不能得出稳定提速的结论。画像耗时约减少 23%,计算阶段的内存占用没有明显改善。 全进程峰值也包含数据生成,分别约为分箱 1907.7→959.9 MiB、独立画像 753.1→742.5 MiB; 画像数据准备造成的峰值波动较大,不能据此宣称内存优化。
sampler 每 10 ms 采样 RSS,总峰值取全程和计算阶段 sampler 观察到的最大值,可能漏掉更短暂的峰值。 输入准备完成后,另启 sampler 测量计算阶段;增量以这个阶段的起始 RSS 为基准。画像在独立进程中测量,避免此前评估留下的内存池影响结果。 没有把 Polars clone 当作底层全复制。不同硬件、线程、dtype、箱数及基准策略需要重新测量; 未验证百万行、3,000 特征或监督分箱器的大规模收益。
--tables-output 可将小结果表保存到临时目录供数值对照;本次固定数据的 19 张画像/风险表
已与优化前源码逐表比较(包括 schema,浮点容差 1e-6)。通常不需要在性能测量时保存表。
既有分箱与规则基准¶
python benchmarks/benchmark_binning_speed.py native \
--rows 200000 --features 3000 --repeats 1
python benchmarks/benchmark_binning_speed.py optimal \
--rows 50000 --features 1000 --repeats 3
python benchmarks/benchmark_rule_mining.py \
--engine mars --rows 100000 --features 1000 --max-candidates 5000 \
--output-json benchmarks/results/mars-rule.json
python benchmarks/benchmark_rule_mining.py \
--engine deimos --rows 100000 --features 1000 --max-candidates 5000 \
--output-json benchmarks/results/deimos-rule.json \
--baseline-root ../deimos-rule
python benchmarks/benchmark_rule_mining.py \
--engine gate \
--mars-result benchmarks/results/mars-rule.json \
--deimos-result benchmarks/results/deimos-rule.json
python benchmarks/benchmark_rule_stages.py \
--stage all --rows 10000 --rules 100 --repeats 3 \
--output-json benchmarks/results/rule-stages-current.json
python benchmarks/benchmark_rule_stages.py \
--stage all --rows 10000 --rules 100 --repeats 3 \
--baseline-json benchmarks/results/rule-stages-before.json
Native 对比需要额外安装 toad;Optimal 对比使用基础依赖中的 optbinning。
规则发布门禁要求在相同机器、环境和数据上,对比 deimos-rule
e6714c5e795054e44f0c58ad7097668b4117b4a2 的组合生成与评估:MARS 总耗时不得退化超过 15%,
进程峰值 RSS 不得退化超过 20%。普通 CI 只运行 2k×20 smoke;100k×1000 对比在发布前手工运行。
子阶段 benchmark 分别覆盖 evaluator、压缩位图 IoU、命中矩阵 analysis 和 cascade。在同一机器预热后,
分别独立运行 3 次并取中位数。发布门禁要求 evaluator、IoU、analysis 相对改造前各至少提速 30%,
峰值 RSS 不得退化超过 10%。rule-stages-before.json 必须来自相同 commit 依赖环境和工作负载。
参考提交使用旧版构造签名 MarsStatsSelector(target=..., features=...)。
benchmark 只在测量脚本(harness)中将这处调用改为当前的 fit(..., target=..., features=...),预筛参数和排序口径不变。
0.0.28 规则门禁结果¶
2026-08-12,在同一台 Windows 机器和 mars Conda 环境中,分别启动独立进程测量 Mars 与 deimos。
两者均使用已验证的 √预算单规则池和二阶 AND/OR 候选口径。切点完整精度和稳定排序存在差异,
最终候选数相差 30 条(0.7%)。
| 项目 | Mars 0.0.28 | deimos e6714c5 |
比值 / 门槛 |
|---|---|---|---|
| 组合生成+评估耗时 | 12.094 s | 10.888 s | 1.1108 / ≤ 1.15 |
| 进程峰值 RSS | 2806.6 MB | 2756.8 MB | 1.0181 / ≤ 1.20 |
| 候选规则数 | 4240 | 4270 | 仅作工作量校验 |
在同一环境中,对 10,000×100 的分阶段工作负载预热后,独立运行 3 次并取中位数。原始结果保存在
benchmarks/results/mars_rule_stages_0_0_28.json:
| 子阶段 | 中位耗时 | 峰值 RSS | 校验值 |
|---|---|---|---|
| evaluator | 0.0282 s | 266.8 MB | 1800 |
| IoU | 0.0068 s | 267.2 MB | 5 |
| analysis | 0.7921 s | 323.4 MB | 4950 |
| cascade | 0.0222 s | 302.6 MB | 1 |
客户指标的计算从逐条规则处理 Python 集合改为一次性因子化后,在同一工作负载上,analysis 从 5.3525 s 降至 0.7921 s(85.2%),峰值 RSS 从 312.9 MB 增至 323.4 MB(3.4%)。
环境:Python 3.10.19、Polars 1.37.1、NumPy 2.2.6、scikit-learn 1.7.2、Windows
10.0.26200、Intel Core i7-14650HX(24 逻辑核)、63.7 GiB 内存。工作负载为 100,000 行、
1,000 个 float32 特征、n_bins=10、max_candidates=5000、batch_size=100、随机种子 42。
测量口径¶
- 分箱计时范围:数据生成、fit、WOE transform 和本轮清理。
- 规则计时范围:预先构造同一宽表,计入特征预筛、候选生成和长表评估,不计数据生成。
- 内存口径:主进程及子进程 RSS 的采样峰值和结束增量。
- MARS 与竞品分别构造对应 DataFrame,结果包含各自数据构造成本。
- Python、Polars、竞品版本和线程设置都会影响结果,不能跨环境直接比较绝对数值。
0.0.24 结果发布清单¶
填写正式结果表前,必须记录以下信息:
| 项目 | 必填内容 |
|---|---|
| MARS | 0.0.24 和 commit SHA |
| Runtime | Python、Polars、NumPy、竞品版本 |
| Hardware | CPU 型号、逻辑核心数、内存容量 |
| System | 操作系统和架构 |
| Workload | 行数、特征数、分箱数、重复次数、随机种子 |
| Result | 每轮耗时、平均耗时、峰值 RSS、校验值 |
| Date | 基准执行日期 |
在完整记录生成前,README 和首页不使用“快数倍”“更省内存”等无条件性能宣传。
公共报告消费的针对性测量¶
运行 python benchmarks/benchmark_report_consumption.py。脚本直接构造统计表,不执行拟合。
2026-10-01 原始结果保存在 benchmarks/results/report_consumption_20261001.json。
环境为 Windows 10.0.26200、Intel Core i7-14650HX、24 逻辑核、63.7 GiB 内存,
Python 3.10.19、Pandas 2.3.3、Polars 1.37.1。运行时没有并行测试或文档构建。
工作负载包含 10,000 行 Pandas overview,以及 1 个特征、365 个日期列的 stats.mean。 分页参数为 offset=9000、limit=10。查询和上下文操作各运行 10 次并取中位数,保存和恢复各运行 3 次。
| 操作 | 中位耗时 | Python 分配峰值 | 校验结果 |
|---|---|---|---|
| 分页 | 0.211 ms | 9,549 B | 返回 10 行,总数 10,000 |
| 16,000 字符上下文 | 33.950 ms | 2,126,371 B | 13,487 字符;保留全部 365 天 |
| 5,000 字符上下文 | 198.513 ms | 2,120,399 B | 4,988 字符;保留 92 天,省略 273 天并给出位置 |
| 完整保存 | 94.228 ms | 4,511,040 B | 单文件 587,148 B |
| 完整恢复 | 60.756 ms | 5,539,585 B | 无原始宽表或分析器 |
字符计数覆盖最终 JSON 的全部内容。tracemalloc 只记录 Python 分配,不包含 Arrow、Polars 等原生内存,
也不等于进程 RSS。较小预算需要更多裁剪步骤,因此耗时更高。这里记录本机的绝对测量值;
没有旧版对照,无法证明提速或峰值内存改善。本轮没有重跑大规模拟合矩阵。