review(follow-ups): 落地上轮建议并给出实测结论(#2/#4 回退、#3 不重写)

一、Tools 完善
* OffscreenChecks `edgestats`:改为自动挑"最有起伏"的信号。旧实现固定取
  `signals[0]`,而 MF4 的第一条信号是常量(6000)⇒ 三个阈值的断言退化成
  "0 == 0" 的空转。现在扫描前 200 条挑 `max-min` 最大者,SCATTER_TEST 上
  三个阈值分别得到 (20,19)/(20,19)/(20,19),与独立参考实现逐位相同。
* UnitTests 新增 `stdio_mingw_vs_ucrt_formats`:把 MinGW ANSI stdio 与系统
  UCRT 的 printf 在**本程序实际用到的全部格式**(`%.*f` / `%.6g` / `%g` /
  `%.4e` / `%.2f %ls` / `%llu` / `%lld` / `%02X` / `%.2f%%`)上做逐字符比对,
  13.6 万次调用 **0 处差异**(覆盖 1e-40~1e40)。它是"把 swprintf 让给 UCRT"
  这条体积优化的验收标准。
* Tools/README.md:同步新增用例与断言数量(219 项 / 18 用例)。

二、第 33 轮报告 §10 后续建议的结论(详细数字见 Progress 第 34 轮)

1. **`EdgeScanFor` 状态查找哈希化:实测后回退。**
   实现方式为 `deque` + `unordered_multimap<keyHash, EdgeScanState*>`(桶内仍
   逐字段比对,碰撞安全;新建/淘汰/定向作废/清空四处同步索引),功能与像素
   验证全绿。但 198 个状态的整轮查询只从 0.097 降到 0.073 us/query(一轮省
   ≈4.8 us),而产物体积 +5,632 B。⇒ 回退。
   同时修正报告的量级:原估"288 信号 ≈0.3ms/帧",实测 ≈20us/帧。

2. **`EdgePanelLayoutFor` 表驱动化:不做。** 实测 1.9~2.5 us/次(每帧约 14 次
   ≈30us),不是热点;第 33 轮已消除"按种类分派"的重复,剩余 957 行是几何算式
   本身,无法表驱动。本轮改为交付"让这类重写可验证"的手段:
   `-run panels -mode record/compare` 逐面板比对几何 + 像素哈希。

3. **`wcstod` 自写替身:实测 0 字节收益。** 只加
   `-D__USE_MINGW_ANSI_STDIO=0` 全量重编后产物仍是 788,480 B、`mingw_wpformat.o`
   仍被链接。原因是预编译 libstdc++ 自己引用 `__mingw_swprintf`:只要还调用
   `std::to_wstring` / `std::to_string`(全仓约 80 处,若干处实参是浮点),
   gdtoa 必然被链入。⇒ 回退,并在 Makefile 留下说明防止重复尝试。

三、文档
* `Documents/Code_Review_Plan.md` 新增 §六(第 34 轮节点与验收标准)。
* `Documents/Code_Review_Progress.md` 新增第 34 轮逐节点记录(含全部实测数字)。
* `Documents/Code_Review_Report.md` 新增 §11(结论表 + 两处量级修正 + 更新的后续建议)。
* `Documents/agent_mem.md` 新增第 34 轮规则:Tools 约定、两个构建陷阱、
  两条"别再重复做"的实验结论。

验证:
* `make release`(删 .o 全量)零 error / 零 warning,产物 **788,480 B**(与改动前一致)。
* `make -C Tools` 零 error / 零 warning。
* `UnitTests.exe` → checks=219 failed=0 cases=18。
* `OffscreenChecks.exe -all` → 5/5 检查 PASS,checks=71 failed=0。
This commit is contained in:
DeepSeek V4.1 Flash committed 2026-11-04 11:52:10 +08:00
1 parent 97e9163314
commit 5c48bf922e
8 files changed
+418 -2

No files matched your search

+23 -1
View File
@@ -491,7 +491,29 @@ namespace jdi
{
return CheckFailed();
}
const SignalData& signal = group->signals[0];
// 挑一条"最有起伏"的信号:常量信号(只有 1 个不同取值)上任何阈值都得不到边沿,
// 断言会退化成"0 == 0"的空转(MF4 的第一条信号就是常量)。
const SignalData* chosen = nullptr;
double chosenSpan = -1.0;
for (const SignalData& candidate : group->signals)
{
double low = 0.0;
double high = 1.0;
FiniteRange(candidate.values, low, high);
const double span = high - low;
if (candidate.values.size() >= 4 && span > chosenSpan)
{
chosen = &candidate;
chosenSpan = span;
}
}
Expect(chosen != nullptr && chosenSpan > 0.0, "found a non-constant signal");
if (chosen == nullptr || !(chosenSpan > 0.0))
{
return CheckFailed();
}
const SignalData& signal = *chosen;
const TimeAxis& axis = group->AxisOf(signal);
const SignalStyle& style = signal.style;
+2 -1
View File
@@ -124,11 +124,12 @@ SUMMARY checks=<n> failed=<m> cases=<k> result=<PASS|FAIL>
| `filter_moving_average_equivalence` | 1 阶 ≡ 单次、2 阶 ≡ 链式、常数信号不变 | 均值滤波多阶 |
| `dataset_group_access` | `AddGroup` / `GroupAt` / `Style(ref)` 读写 | 数据层入口 |
| `dataset_formula_transform_cache` | 值域 + 逐分组极值 vs 逐点参考**逐位相同**;命中同指针;样式变化失效 | 第 32 轮核心缓存的正确性 |
| `stdio_mingw_vs_ucrt_formats` | MinGW ANSI stdio 与系统 UCRT 的 printf 在**本程序用到的全部格式**上逐字符比对(13.6 万次调用) | 评估“把 `swprintf` 交给 UCRT”是否可行(当前 0 差异);将来真做迁移就是验收标准 |
### 3.2 验收标准
* **零失败**(`result=PASS`)才算通过;
* 断言数量只增不减(当前 **218** 项):删断言必须说明理由;
* 断言数量只增不减(当前 **219** 项 / 18 个用例):删断言必须说明理由;
* 任何"为了让它过"而放宽的断言,必须在代码注释里写清依据。
---
+130
View File
@@ -13,12 +13,17 @@
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cwchar>
#include <random>
#include <string>
#include <vector>
#include <stdio.h>
#include <wchar.h>
#include "UnitTestFramework.hpp"
#include "Utf8Util.hpp"
@@ -304,3 +309,128 @@ JDI_TEST(ticks_nice_step_and_build_ticks)
JDI_CHECK_NEAR(ticks.back(), 10.0, 0.0);
}
}
/**
* @brief MinGW ANSI stdio 与 UCRT printf 在**本程序实际使用的格式**上是否逐字符一致。
*
* 用途:评估"把 `swprintf` 让给系统 UCRT 实现(`__USE_MINGW_ANSI_STDIO=0`)"
* 这条体积优化是否可行 —— 若成立可以省掉整个 `mingw_wpformat` + `gdtoa` 链(≈33KB)。
* 判据极其严格:**逐字符相同**,一个字符的差异都不接受(显示文本是产品语义)。
*/
JDI_TEST(stdio_mingw_vs_ucrt_formats)
{
std::mt19937 rng(20261107u);
std::uniform_real_distribution<double> distribution(-1.0e7, 1.0e7);
std::uniform_real_distribution<double> magnitude(-40.0, 40.0);
int mismatches = 0;
int compared = 0;
static const int decimalsList[] = {0, 1, 2, 3, 4, 6, 8, 12};
for (int iteration = 0; iteration < 8000; ++iteration)
{
double value = distribution(rng);
// 覆盖极小 / 极大 / 整数量级,以及 FormatDecimal 会遇到的量级
if ((iteration % 7) == 0)
{
value = std::pow(10.0, magnitude(rng)) * ((iteration % 2 == 0) ? 1.0 : -1.0);
}
if ((iteration % 11) == 0)
{
value = static_cast<double>(iteration);
}
wchar_t ours[128] = {};
wchar_t theirs[128] = {};
for (const int decimals : decimalsList)
{
swprintf(ours, 128, L"%.*f", decimals, value);
_snwprintf(theirs, 128, L"%.*f", decimals, value);
++compared;
if (wcscmp(ours, theirs) != 0)
{
if (mismatches < 5)
{
std::printf(" [INFO] %%.%df value=%.17g ours=\"%ls\" ucrt=\"%ls\"\n", decimals, value, ours,
theirs);
}
++mismatches;
}
}
struct WideFormatProbe
{
const wchar_t* format;
};
static const WideFormatProbe probes[] = {{L"%.6g"}, {L"%.4e"}, {L"%.2f"}, {L"%g"}};
for (const WideFormatProbe& probe : probes)
{
swprintf(ours, 128, probe.format, value);
_snwprintf(theirs, 128, probe.format, value);
++compared;
if (wcscmp(ours, theirs) != 0)
{
if (mismatches < 5)
{
std::printf(" [INFO] \"%ls\" value=%.17g ours=\"%ls\" ucrt=\"%ls\"\n", probe.format, value,
ours, theirs);
}
++mismatches;
}
}
// 非浮点格式(颜色十六进制 / 计数 / 百分比尾缀)
const unsigned long long counter = static_cast<unsigned long long>(iteration) * 7919ull;
swprintf(ours, 128, L"%llu", counter);
_snwprintf(theirs, 128, L"%llu", counter);
++compared;
if (wcscmp(ours, theirs) != 0)
{
++mismatches;
}
swprintf(ours, 128, L"%02X%02X%02X", iteration & 0xFF, (iteration >> 3) & 0xFF, (iteration >> 6) & 0xFF);
_snwprintf(theirs, 128, L"%02X%02X%02X", iteration & 0xFF, (iteration >> 3) & 0xFF,
(iteration >> 6) & 0xFF);
++compared;
if (wcscmp(ours, theirs) != 0)
{
++mismatches;
}
swprintf(ours, 128, L"%.2f%%", value / 1000.0);
_snwprintf(theirs, 128, L"%.2f%%", value / 1000.0);
++compared;
if (wcscmp(ours, theirs) != 0)
{
++mismatches;
}
// `%ls`:`FormatByteSize` 的 `%.2f %ls` 依赖"宽格式串里的 %ls = 宽字符串"。
// ⚠️ MSVC/UCRT 的宽 printf 里 `%s` 也表示**宽**字符串,与 MinGW ANSI(`%s`=窄)相反,
// 因此全仓禁止在宽格式串里写 `%s`(已有注释约束),这里顺带把 `%ls` 也钉住。
swprintf(ours, 128, L"%.2f %ls", value / 1024.0, L"MB");
_snwprintf(theirs, 128, L"%.2f %ls", value / 1024.0, L"MB");
++compared;
if (wcscmp(ours, theirs) != 0)
{
if (mismatches < 5)
{
std::printf(" [INFO] \"%%.2f %%ls\" ours=\"%ls\" ucrt=\"%ls\"\n", ours, theirs);
}
++mismatches;
}
swprintf(ours, 128, L"%lld", static_cast<long long>(iteration) * -7919ll);
_snwprintf(theirs, 128, L"%lld", static_cast<long long>(iteration) * -7919ll);
++compared;
if (wcscmp(ours, theirs) != 0)
{
++mismatches;
}
}
std::printf(" [INFO] compared %d format calls, %d mismatches\n", compared, mismatches);
JDI_CHECK_EQ(mismatches, 0);
}