From 56c89c5fa4ed2dab1e905892266c51d3fc1db8fa Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Wed, 28 Oct 2026 22:09:48 +0800 Subject: [PATCH] =?UTF-8?q?diag:=20=E6=8B=86=E5=88=86"=E5=86=99=E4=B8=B4?= =?UTF-8?q?=E6=97=B6=E6=96=87=E4=BB=B6"=E4=B8=8E"acisIn"=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=88=A4=E5=AE=9A=E5=86=85=E5=AD=98=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E4=B8=8D=E5=80=BC=E5=BE=97=E5=81=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修完回写后开图期仍有 1733 次临时文件写入,需要判断"改内存读取"能省多少。 在 RegionAcisInDwgInFields 与 CoreTools::StringToRegion 两个重载里,把 "写临时文件+关闭"和"AcDbBody::acisIn"拆成独立计时(RegIn.write / RegIn.acisIn / Str2Reg.write / Str2Reg.acisIn)。 实测(big1.dwg,93 s 开图,1733 次未命中): RegIn.write 374 次 70.5 ms 189 us RegIn.acisIn 374 次 1422.0 ms 3.80 ms Str2Reg.write 1359 次 267.7 ms 197 us Str2Reg.acisIn 1359 次 5999.5 ms 4.41 ms 结论:写文件合计 338 ms,只占 9.6 s 恢复耗时的 3.5%;杀软扫描已在 write 的 190 us 里 (Defender 在关闭时扫)。即使完全省掉文件往返,上限也只有 0.3~0.5 s(开图的 0.4%)。 而 AcDbBody::acisIn 在 R19~R26 只有文件名重载,真要内存解析只能改存盘格式走 acdbModelerRestoreEntityFromDwgFiler(即暂缓的 Phase 3)。因此不做。 剩余 7.4 s 是纯解析(1733 次 × 4.3 ms),只能靠减少次数;text 通道 1560 个唯一文本 是真实不同的截面,命中率已接近上限。继续提速应转向 Parasolid 绘制那条线。 数据与结论已写入 pipe-section-region-performance-plan.md。 本次只加诊断计时(Debug + AEC_PERF_COUNTER=1 才生效),不改任何业务行为。 --- SourceCode/Code2026/CoreCommand/CoreTools.cpp | 32 +++++++++++++++---- .../Code2026/CoreLibrary/AecDbEwPipeBase.cpp | 13 ++++++-- pipe-section-region-performance-plan.md | 25 +++++++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/SourceCode/Code2026/CoreCommand/CoreTools.cpp b/SourceCode/Code2026/CoreCommand/CoreTools.cpp index 51782a9..12f780d 100644 --- a/SourceCode/Code2026/CoreCommand/CoreTools.cpp +++ b/SourceCode/Code2026/CoreCommand/CoreTools.cpp @@ -3564,8 +3564,11 @@ AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp) if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite)) { - file.Write(sNewSrc.c_str(), sizeof(char) * (UINT)sNewSrc.size()); - file.Close(); + { + SectionPerf::Scope w("Str2Reg.write"); + file.Write(sNewSrc.c_str(), sizeof(char) * (UINT)sNewSrc.size()); + file.Close(); + } SectionPerf::NoteTempFile(sNewSrc.size()); } else @@ -3577,7 +3580,11 @@ AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp) AcDbRegion *pReg(NULL); AcDbVoidPtrArray arBodyPtrs; - Acad::ErrorStatus es(AcDbBody::acisIn(sFullPath, arBodyPtrs)); + Acad::ErrorStatus es(Acad::eOk); + { + SectionPerf::Scope r("Str2Reg.acisIn"); + es = AcDbBody::acisIn(sFullPath, arBodyPtrs); + } if (Acad::eOk == es) { if (arBodyPtrs.length() > 0) @@ -3646,8 +3653,11 @@ AcDbRegion *CoreTools::StringToRegion(Adesk::UInt64 nLen, char *pszReg) CFile file; if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite)) { - file.Write(sNewSrc.c_str(), sizeof(char) * (UINT)sNewSrc.size()); - file.Close(); + { + SectionPerf::Scope w("Str2Reg.write"); + file.Write(sNewSrc.c_str(), sizeof(char) * (UINT)sNewSrc.size()); + file.Close(); + } SectionPerf::NoteTempFile(sNewSrc.size()); } else @@ -3658,7 +3668,11 @@ AcDbRegion *CoreTools::StringToRegion(Adesk::UInt64 nLen, char *pszReg) } AcDbVoidPtrArray arBodyPtrs; - Acad::ErrorStatus es(AcDbBody::acisIn(sFullPath, arBodyPtrs)); + Acad::ErrorStatus es(Acad::eOk); + { + SectionPerf::Scope r("Str2Reg.acisIn"); + es = AcDbBody::acisIn(sFullPath, arBodyPtrs); + } if (Acad::eOk == es) { if (arBodyPtrs.length() > 0) @@ -3760,7 +3774,11 @@ AcDbSurface *CoreTools::StringToFace(Adesk::UInt64 nLen, char *pszBody) } AcDbVoidPtrArray arBodyPtrs; - Acad::ErrorStatus es(AcDbBody::acisIn(sFullPath, arBodyPtrs)); + Acad::ErrorStatus es(Acad::eOk); + { + SectionPerf::Scope r("Str2Reg.acisIn"); + es = AcDbBody::acisIn(sFullPath, arBodyPtrs); + } if (Acad::eOk == es) { if (arBodyPtrs.length() > 0) diff --git a/SourceCode/Code2026/CoreLibrary/AecDbEwPipeBase.cpp b/SourceCode/Code2026/CoreLibrary/AecDbEwPipeBase.cpp index d773b8e..fb8486b 100644 --- a/SourceCode/Code2026/CoreLibrary/AecDbEwPipeBase.cpp +++ b/SourceCode/Code2026/CoreLibrary/AecDbEwPipeBase.cpp @@ -921,15 +921,22 @@ AcDbRegion* AecDbEwPipeBase::RegionAcisInDwgInFields(AcDbDwgFiler* pFiler) return NULL; } - file.Write(pszTxt,nLen); - file.Close(); + { + SectionPerf::Scope w("RegIn.write"); + file.Write(pszTxt,nLen); + file.Close(); + } delete[] pszTxt; // 读侧落盘的临时文件次数/字节(杀软扫描影响面) SectionPerf::NoteTempFile((size_t)nLen); AcDbVoidPtrArray arBodyPtrs; - Acad::ErrorStatus es = AcDbBody::acisIn(sFullPath,arBodyPtrs); + Acad::ErrorStatus es = Acad::eOk; + { + SectionPerf::Scope r("RegIn.acisIn"); + es = AcDbBody::acisIn(sFullPath,arBodyPtrs); + } if (es != Acad::eOk) { acutPrintf(_T("\nAecDbEwPipeBase: 截面 acisIn 失败,len=%u,err=%d。"),nLen,es); diff --git a/pipe-section-region-performance-plan.md b/pipe-section-region-performance-plan.md index 8f8a7d1..7100400 100644 --- a/pipe-section-region-performance-plan.md +++ b/pipe-section-region-performance-plan.md @@ -414,6 +414,31 @@ pClone->dwgIn(&filer); // → dwgInFields → acisIn 读回来 `ToJson()` 靠 `BuildSectionFromXData()` 重建,需要实际触发一次导出, 确认 `__pipes__` 里每条仍有 `__section__` / `__section2__` 且数值与改动前一致。 +### 是否改用"内存读取"?——实测后决定不做 + +修完回写之后,开图期仍有 **1733 次临时文件写入**(2.34 MB),自然会想: +如果 `acisIn` 能从内存读,不就省掉 I/O 和杀软扫描了吗? + +把"写文件"和"acisIn"分开计时后(`RegIn.write` / `RegIn.acisIn` / `Str2Reg.write` / `Str2Reg.acisIn`): + +| 环节 | 次数 | 总耗时 | 平均 | +| --- | ---: | ---: | ---: | +| `RegIn.write`(实体路径,写+关闭,含杀软扫描) | 374 | **70.5 ms** | 189 µs | +| `RegIn.acisIn` | 374 | 1422 ms | 3.80 ms | +| `Str2Reg.write` | 1359 | **267.7 ms** | 197 µs | +| `Str2Reg.acisIn` | 1359 | 5999 ms | 4.41 ms | + +**写文件合计只有 338 ms,占 9.6 s 恢复耗时的 3.5%**,其余 7.4 s 是 `acisIn` 解析文本本身。 +杀软扫描的时间已经包含在 `write` 的 190 µs 里(Defender 在关闭时扫),不是额外开销。 + +结论:即使完全省掉文件往返,最多省 0.3~0.5 s(开图的 0.4%)——**不值得做**。 +而且 `AcDbBody::acisIn` 在 R19~R26 只有文件名重载,真要"内存解析"只能改存盘格式 +走 `acdbModelerRestoreEntityFromDwgFiler`(即此前评估后暂缓的 Phase 3)。 + +剩下的 7.4 s = 1733 次 × 4.3 ms 的纯解析,只能靠减少解析次数, +而 text 通道的 1560 个唯一文本是**真实不同的截面**,命中率已接近上限。 +继续提速应转向 Parasolid 绘制那条线(早先 trace 里独占约 43%),不是截面恢复。 + ### Phase 2:临时目录治理(可选,止血) Phase 1 之后残余落盘只剩"每个唯一截面一次",收益小;但如果现场仍被杀软拖慢,可做这一步: