perf: 护栏/爬梯等构件的管道副本改为"只存参数",消除开图期 1140 次截面回写
现象:开图期间 AecDbEwPipeBase::RegionAcisoutDwgOutFields 被调用 1140 次、耗时 2.38 s, 把截面写成临时 SAT 文件。用 AEC_WRITEBACK_TRACE 抓栈 + tools/resolve_rva.ps1 解符号, 定位到 AecDbZLineStair::DrawGuarBar3d 里的 pipe.clone(): clone 走 AcDbObject → AecDbEwPipeBase::copyFrom → CopyObject(整实体 dwgOutFields/dwgInFields 往返),于是截面被写成临时文件再读回。 这些 clone 的唯一用途是存进 m_pipes,供 ToJson() 导出 __pipes__,而截面参数在 SetSection 时已经写进 spec XData(KEY_SECSHAPE / KEY_SIZE1 / KEY_SIZE2 / PIPE_THICK / KEY_SECCEN),完全可以按参数重建。因此把"建几何"推迟到导出时: - AecDbEwPipeBase::BuildSectionFromXData():按 XData 参数重建截面(圆形/矩形; 自定义截面返回 NULL,那种只能存在于 SAT 里) - AecDbEwPipeBase::CloneParamsOnly():生成只带参数(XData、放样线、实体属性、GUID、 Breaks)、不含截面几何的副本,不触发任何序列化 - AecDbEwPipeBase::ToJson():GetSection() 为空时回退到 BuildSectionFromXData(), 保证 __section__ / __section2__ 仍然导出 - 30 处 m_pipes.push_back((AecDbEwPipe*)pipe.clone()) 改为 pipe.CloneParamsOnly(): ClimbStair(10)、ZLineStair(6)、BossHolder(4)、MRPLineStair(4)、Hanger(3)、Holder(3) 过程:先只改楼梯两个文件,回写从 1140 降到 960;再抓栈解析出剩余 960 全部来自 AecDbClimbStair::DrawLadderH3d,于是把其余 20 处一并改掉,最终归零。 实测(big1.dwg / AutoCAD 2020 / R230 Debug): 开图墙钟 初始 108~113 s -> 缓存后 98 s -> 本次 93 s 开图期回写 1140 次/2.38 s -> 1140 次 -> 0 RegionAcisIn 3082 次 -> 3082 次 -> 1942 次 临时文件 6773/9.34MB -> 2694/3.34MB -> 1733/2.34MB 截面恢复总耗时 22.4 s -> 9.87 s -> 9.4 s 另外把 SectionPerf::TraceCallStack 的输出改写到独立的 aec_writeback_trace.txt, 不再写进 ENVIPERFDUMP 的报告文件(否则脚本会把"栈写出来了"误判成"开图完成")。 验证:R230 Debug 编译通过并部署;用 tools/run_acad_perf.ps1 自动开图取数。 待验证:JSON 导出。m_pipes 里现在是不含几何的参数副本,ToJson 靠 BuildSectionFromXData() 重建,需要实际触发一次导出,确认 __pipes__ 里每条仍有 __section__ / __section2__ 且与改动前一致。
This commit is contained in:
1 parent
7038a98441
commit
b981fe930a
10 files changed
+146
-31
No files matched your search
@@ -1003,7 +1003,7 @@ AcDb3dSolid* AecDbHanger::Create3dRod(const AcGePoint3d& ptFr,const AcGePoint3d&
|
||||
pipe.SetSection(dL1,0.0);
|
||||
pipe.SetStartPoint(ptFr);
|
||||
pipe.SetEndPoint(ptTo);
|
||||
m_pipes.push_back((AecDbEwPipe*)pipe.clone());
|
||||
m_pipes.push_back(pipe.CloneParamsOnly()); // 只存参数,截面在 ToJson() 时重建
|
||||
|
||||
pipe.Draw3d(dcTmp);
|
||||
pPipe = pipe.GetCreatPipe3dSolid();
|
||||
@@ -1015,7 +1015,7 @@ AcDb3dSolid* AecDbHanger::Create3dRod(const AcGePoint3d& ptFr,const AcGePoint3d&
|
||||
pipe.SetSectionRotation(dRegRoate);
|
||||
pipe.SetStartPoint(ptFr);
|
||||
pipe.SetEndPoint(ptTo);
|
||||
m_pipes.push_back((AecDbEwPipe*)pipe.clone());
|
||||
m_pipes.push_back(pipe.CloneParamsOnly()); // 只存参数,截面在 ToJson() 时重建
|
||||
|
||||
pipe.Draw3d(dcTmp);
|
||||
pPipe = pipe.GetCreatPipe3dSolid();
|
||||
@@ -1027,7 +1027,7 @@ AcDb3dSolid* AecDbHanger::Create3dRod(const AcGePoint3d& ptFr,const AcGePoint3d&
|
||||
pipe.SetSectionRotation(dRegRoate);
|
||||
pipe.SetStartPoint(ptFr);
|
||||
pipe.SetEndPoint(ptTo);
|
||||
m_pipes.push_back((AecDbEwPipe*)pipe.clone());
|
||||
m_pipes.push_back(pipe.CloneParamsOnly()); // 只存参数,截面在 ToJson() 时重建
|
||||
pipe.Draw3d(dcTmp);
|
||||
pPipe = pipe.GetCreatPipe3dSolid();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user