feat: replace mapping generation with checked copy utilities
This commit is contained in:
70
reports/copyxAcceptance.md
Normal file
70
reports/copyxAcceptance.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# v0.19 copyx 与映射移除验收
|
||||
|
||||
日期:2026-09-25。环境:Apple M2 Max、darwin/arm64、Go 1.27.1,基准默认 GOMAXPROCS=12。最低支持版本另用 Go 1.22.12 验证 copyx 与可运行示例。
|
||||
|
||||
## 范围与行为
|
||||
|
||||
本轮新增可选 Go 工具包并删除原映射配置/生成机制,没有修改接入项目代码、数据库或线上服务。没有新增第三方依赖,没有内置工资、金额或权限规则;工资只是生成器的独立通用验收 fixture。
|
||||
|
||||
| 场景 | 验证内容 |
|
||||
| --- | --- |
|
||||
| 浅/深复制 | 值、结构、指针、数组、map、slice、interface;浅共享与深隔离分别验证 |
|
||||
| 空值与精度 | nil 与空集合、默认保留 false/0、显式 nil/skip 策略;不兼容类型不能借 nil/零值绕过检查 |
|
||||
| 可变引用 | 原指针/map、子切片、零长度但有容量的视图、源元素指针、私有子引用、其他字段的引用均拒绝 |
|
||||
| 自定义函数 | 字段改名、精确类型对、金额私有状态复制、nil interface;重复/冲突配置拒绝 |
|
||||
| 失败语义 | errors.Is 保留 cause、目标不提交部分结果、嵌入目标指针不提前修改 |
|
||||
| 对象图 | 指针/map/slice 循环,重复引用;循环指针根压成值结构拒绝 |
|
||||
| 并发与资源 | 同一 Copier 64 goroutine 各复制 20 次,race;深度/节点/估算分配超限拒绝;锁/资源/函数等明确限制 |
|
||||
| 真正生成的消费者 | 三端工资公共字段,Money scalar,大数精度/舍入、非法金额、缺失/null/零值、完整表单、错误码与错误链 |
|
||||
| 维护成本 | 公共字段新增:改一处契约和一处独立业务结构;三个接口共用 helper,不增加拷贝规则 |
|
||||
| 生成与生命周期 | 重复 generate/check/dry-run 保留业务文件;工厂异常、初始化/监听失败及资源关闭由既有回归验证 |
|
||||
| 移除与 workspace | 旧配置/旧生成文件阻断且不写入,明确迁移后所有权清理;workspace 失败不部分更新服务 |
|
||||
|
||||
FuzzClone 使用动态 JSON 容器、随机 bytes 和嵌套 slice,验证值一致与引用隔离。输入超过 1 KiB 时截取继续验证,运行 30 秒、4 workers:**4,237,917 次执行,未发现失败**。这不等于所有形状都已 fuzz;循环、类型转换及资源拒绝另外用定向用例覆盖。
|
||||
|
||||
全量 46 个测试包通过 race 回归(含实际生成项目),vet/build、Go 1.22.12、示例运行与生成漂移检查均通过。
|
||||
|
||||
## 可复现命令
|
||||
|
||||
```sh
|
||||
GO_OMNI_SCAFFOLD_INTEGRATION=1 go test -race -count=1 ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
GOTOOLCHAIN=go1.22.12 go test ./copyx ./examples/copying
|
||||
go test ./copyx -run '^$' -fuzz FuzzClone -fuzztime 30s -parallel 4
|
||||
go test ./copyx -run '^$' -bench . -benchmem -benchtime 300ms -count 3
|
||||
go run ./examples/copying
|
||||
go run ./cmd/go-omni api generate --dir examples/managedService --check
|
||||
# examples/managedService 中另执行 go test -race ./... 与 go build .
|
||||
```
|
||||
|
||||
全量回归包含真实临时生成项目,集成测试的子进程使用 go test -race / go build,并不只比较生成字符串。基准测量时没有同时运行本轮 fuzz 或全量测试;原始三轮结果见 [copyxBenchmark.txt](copyxBenchmark.txt)。
|
||||
|
||||
## 性能与分配
|
||||
|
||||
下表取三轮中位数。构造器复用与一次性调用都包含真实复制;`fields1000` 指整数 slice 的长度,不是 1,000 个结构字段。所有深拷贝保留引用检查。
|
||||
|
||||
| 场景 | 中位耗时 | B/op | allocs/op |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| 相同结构浅拷贝(含引用字段) | 85.8 ns | 96 | 2 |
|
||||
| 3 字段跨结构改名,复用 Copier | 697.5 ns | 168 | 7 |
|
||||
| 相同跨结构,每次构建 Copier | 1,181 ns | 1,120 | 17 |
|
||||
| 嵌套结构 + 1 个整数 + map,深拷贝 | 2,758 ns | 1,368 | 42 |
|
||||
| 嵌套结构 + 100 个整数 + map,深拷贝 | 2,787 ns | 2,256 | 42 |
|
||||
| 嵌套结构 + 1,000 个整数 + map,深拷贝 | 3,806 ns | 9,552 | 42 |
|
||||
| 64 KiB byte slice 深拷贝 | 5,780 ns | 65,768 | 9 |
|
||||
| 100 项 map,每项含整数 slice | 88,859 ns | 87,704 | 1,554 |
|
||||
| 自引用循环对象深拷贝 | 2,128 ns | 640 | 26 |
|
||||
| converter 新建 slice 并通过检查 | 539.7 ns | 280 | 10 |
|
||||
| converter 返回原 slice 被拒绝 | 383.8 ns | 320 | 11 |
|
||||
|
||||
并行循环对象基准中位 515.2 ns/op 是多核聚合吞吐均摊,**不是单请求延迟**。复杂 map 的多次图扫描、字段路径和反射分配明显更贵;不据此宣称运行时工具快于手写赋值。热点复用 Copier;大对象和高频映射应按实际业务结构衡量是否改用直接 Go。
|
||||
|
||||
优化只包括不可变类型元数据缓存、纯值快速路径、纯值 slice 批量复制;没有去掉深拷贝别名检查。内置估算分配上限 64 MiB 不是硬堆内存隔离,converter 的外部分配及副作用不受该预算控制。
|
||||
|
||||
## 边界
|
||||
|
||||
- 新方式在运行时做类型与覆盖检查,不再有旧映射生成时的静态保证;字段变更要运行实际类型对测试。
|
||||
- converter 是受信项目代码,必须只读输入;不能自动回滚其副作用、证明其未共享外部全局对象,或强杀无限循环。
|
||||
- 当前记录是本机库/生成器验收,不是线上服务吞吐、Linux soak、真实业务数据库回归或 OSS/R2 云账号验收。本轮没有对线上服务器施压。
|
||||
- 旧消费者仍需按 [COPY.md](../COPY.md#从旧-mapping-迁移) 迁移,不会被这次框架发布自动修改。
|
||||
Reference in New Issue
Block a user