diag: 统计回写的实体类,定位到 AecDbEwPipeBase 基类实例
上一版只抓到"绘制期深拷贝"的调用栈,还没回答"是哪个类的实体在回写"。
现在 SectionPerf 增加按类统计的写回计数(NoteWriteBackClass),
在 RegionAcisoutDwgOutFields 里记一次 isA()->name()。
实测(big1.dwg,开图一次):
---- write-backs by entity class ----
1140 AecDbEwPipeBase
全部 1140 次都是 AecDbEwPipeBase 基类实例,不是 AecDbEwPipe 也不是具名子类,
与属性 key 统计里 AecDbEwPipeBase 的 1172 次几乎一一对应——
说明图纸里约有 1172 个基类实例(由 AecDbAssembleWell.cpp 的装配井代码创建,
多为矩形截面段),绘制期每个被深拷贝一次。
完整链路(已写入计划文档):
base_ViewportDraw -> AecDbCurveBase::subGetTransformedCopy
(AecRxBase/AecDbCurveBase.cpp:307 里的 clone())
-> AecDbEntityCommon::base_DeepClone(AecDbEntityCommon.cpp:1232,dwgOut 在 1265)
-> AecDbEwPipeBase::dwgOutFields(AecDbEwPipeBase.cpp:1440)
-> AecDbEwPipeBase::RegionAcisoutDwgOutFields(AecDbEwPipeBase.cpp:1275)
顺带发现:AecDbEwPipeBase::copyFrom(:1605)复制截面用的是 m_pRegion->copyFrom(),
是内存级 ACIS 拷贝,比"写文件再读回"便宜得多。所以最局部的修法可能是给管系实体
加 subGetTransformedCopy 重载,用 isA()->create()+copyFrom() 代替 clone(),
绕开整条序列化链路;但 clone 与 copyFrom 语义不完全等价,需先核对。
本次只记录分析,不改行为。
验证:R230 Debug 编译通过并部署,脚本自动开图一次得到上述分类统计。
This commit is contained in:
1 parent
67d6545e6c
commit
6d6f9ddaff
4 files changed
+60
No files matched your search
@@ -1289,6 +1289,7 @@ Acad::ErrorStatus AecDbEwPipeBase::RegionAcisoutDwgOutFields(AcDbDwgFiler* pFile
|
||||
|
||||
SectionPerf::Scope perfScope("EwPipe::RegionAcisout");
|
||||
SectionPerf::NoteWriteBack("EwPipe::RegionAcisout");
|
||||
SectionPerf::NoteWriteBackClass(CStringA(isA()->name()));
|
||||
|
||||
if (m_pRegion == NULL)
|
||||
return Acad::eInvalidInput;
|
||||
|
||||
@@ -65,6 +65,9 @@ namespace
|
||||
|
||||
// 属性 key:class 名 -> 唯一/命中统计
|
||||
std::map<std::string, KeyStat> attrStats;
|
||||
|
||||
// 回写次数:实体类 -> 次数
|
||||
std::map<std::string, unsigned long long> writeBackByClass;
|
||||
};
|
||||
|
||||
// 故意用函数内 static:AGENTS.md 禁止文件级 static。
|
||||
@@ -262,6 +265,15 @@ namespace SectionPerf
|
||||
}
|
||||
}
|
||||
|
||||
void NoteWriteBackClass(const char* pszClass)
|
||||
{
|
||||
Stats& s = GetStats();
|
||||
if (!s.bEnabled)
|
||||
return;
|
||||
std::string key(pszClass != NULL ? pszClass : "?");
|
||||
++s.writeBackByClass[key];
|
||||
}
|
||||
|
||||
void Dump()
|
||||
{
|
||||
Stats& s = GetStats();
|
||||
@@ -288,6 +300,18 @@ namespace SectionPerf
|
||||
s.nTempFiles, s.nTempFileBytes, s.nWriteBacks);
|
||||
out += szLine;
|
||||
|
||||
if (!s.writeBackByClass.empty())
|
||||
{
|
||||
out += "---- write-backs by entity class ----\n";
|
||||
out += " count class\n";
|
||||
for (std::map<std::string, unsigned long long>::const_iterator it = s.writeBackByClass.begin();
|
||||
it != s.writeBackByClass.end(); ++it)
|
||||
{
|
||||
sprintf_s(szLine, sizeof(szLine), " %-8llu %s\n", it->second, it->first.c_str());
|
||||
out += szLine;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.attrStats.empty())
|
||||
{
|
||||
out += "---- attr key (by class, would-be cache hit rate) ----\n";
|
||||
@@ -417,5 +441,6 @@ namespace SectionPerf
|
||||
s.nTempFileBytes = 0;
|
||||
s.nWriteBacks = 0;
|
||||
s.attrStats.clear();
|
||||
s.writeBackByClass.clear();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user