From 0cb05b769f2bb1562ceffe3cb6c7e60fb20a402d Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Wed, 28 Oct 2026 10:09:24 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E7=BC=93=E5=AD=98=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=A0=B7=E5=BC=8F=E6=9F=A5=E8=AF=A2=EF=BC=8C?= =?UTF-8?q?=E7=AE=A1=E7=BA=BF/=E7=AE=A1=E4=BB=B6=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E5=8F=8D=E5=A4=8D=E5=BC=80=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AecDbEwPipe / AecDbEwFitting 的 dwgInFields 会给缺失的样式键回填 颜色/线型/线宽/图层(PR #87 引入),走 CoreTools 的 4 个 getter; 每个 getter 都新建 CUIISQLiteServer 开一次 Plumbing.db,内部又调 getCurrentPipeSysTblName 再开一次。单实体最多 16 次 sqlite3_open, 几百个实体的图纸即几千次串行开库;绘制路径(setInfo2Ent / setInfo2Dc)同样走这 4 个 getter。 改为:一条 SQL 取全 COLOR/LINETYPE/LINEWIDTH/LAYNAME,结果按 「表名 + 系统名 + 中心线/外边线」做进程级缓存;表名本身按 getCurrentTrade() 缓存。首次 2 次开库,之后全部内存命中。 - 只改 CoreCommand/CoreTools.cpp,对外签名不变,192 处调用点全覆盖 (CoreLibrary / PipelineCmd / PipelineSpecCmd / HvacCmd) - 缓存只存字符串,AcDbObjectId 仍按当前图纸每次现解析,多文档切换 不串图层/线型 - 保持原语义:库打不开时 getColorByPipeSys 返回 256、getLtByPipeSys 与 getLyByPipeSys 返回空 id、getLwByPipeSys 返回 0 - 缓存生命周期等于进程,改系统样式配置需重启生效;静态对象用故意 不释放的指针持有,避免 DLL 卸载期析构顺序问题 - getPipeColorBySystem 未动:它的 SQL 不带 PIPESYS 过滤,语义与这 4 个 getter 不同,且唯一调用点已被注释 编译验证:R190 Debug 下 AecRxBase / CoreCommand_BAL_REMOTE / CoreLibrary_BAL_REMOTE / CoreImplement 全部通过。 --- SourceCode/Code2026/CoreCommand/CoreTools.cpp | 139 +++++++++++++----- 1 file changed, 105 insertions(+), 34 deletions(-) diff --git a/SourceCode/Code2026/CoreCommand/CoreTools.cpp b/SourceCode/Code2026/CoreCommand/CoreTools.cpp index fdc5d1a..3fb2da2 100644 --- a/SourceCode/Code2026/CoreCommand/CoreTools.cpp +++ b/SourceCode/Code2026/CoreCommand/CoreTools.cpp @@ -4911,7 +4911,15 @@ int CoreTools::getCurrentTrade() CString CoreTools::getCurrentPipeSysTblName() { + //表名随行业变化,所以按 getCurrentTrade() 缓存; + //指针故意不释放,避免 DLL 卸载时的析构顺序问题 + static int *s_pCachedTrade = new int(-1); + static CString *s_pCachedTable = new CString; + int nTrade = getCurrentTrade(); + if (*s_pCachedTrade == nTrade && !s_pCachedTable->IsEmpty()) + return *s_pCachedTable; + CString sRel(_T("WConfig_CN")); CUIISQLiteServer db; if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return sRel; @@ -4924,36 +4932,106 @@ CString CoreTools::getCurrentPipeSysTblName() db.GetSelData(sql, sRel); + + *s_pCachedTrade = nTrade; + *s_pCachedTable = sRel; return sRel; } +namespace +{ + //一个管线系统的四个样式字段,全部按字符串缓存 + struct PipeSysStyle + { + CString sColor; //颜色 + CString sLt; //线型名 + CString sLw; //线宽 + CString sLy; //图层名 + }; + + typedef std::map PipeSysStyleMap; + + //指针故意不释放,避免 DLL 卸载时的析构顺序问题 + PipeSysStyleMap& PipeSysStyleCache() + { + static PipeSysStyleMap *s_pMap = new PipeSysStyleMap; + return *s_pMap; + } + + //一条 SQL 取全四个字段;数据库打不开返回 false + bool QueryPipeSysStyle(LPCTSTR pszSys, bool bCenter, PipeSysStyle& st) + { + CUIISQLiteServer db; + if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return false; + + CString sTable(CoreTools::getCurrentPipeSysTblName()); + CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线"); + + CString sql; + sql.Format(_T("SELECT [COLOR],[LINETYPE],[LINEWIDTH],[LAYNAME] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'") + , sTable, pszSys, pipesys); + + CStringArray arVals; + db.GetSelData(sql, arVals); + + if (arVals.GetSize() < 4) + { //查不到:沿用原来的默认值,也照样缓存,避免配错的系统名反复查库 + st.sColor = _T("256"); + st.sLt = _T("Continuous"); + st.sLw = _T("0"); + st.sLy = _T("0"); + return true; + } + + st.sColor = arVals.GetAt(0); + st.sLt = arVals.GetAt(1); + st.sLw = arVals.GetAt(2); + st.sLy = arVals.GetAt(3); + return true; + } + + //进程级缓存,key = 表名 + 系统名 + 中心线/外边线; + //只缓存字符串,AcDbObjectId 属于当前图纸,由调用方每次现解析 + bool GetPipeSysStyle(LPCTSTR pszSys, bool bCenter, PipeSysStyle& st) + { + CString sKey; + sKey.Format(_T("%s\x01%s\x01%d") + , (LPCTSTR)CoreTools::getCurrentPipeSysTblName(), pszSys, bCenter ? 1 : 0); + + PipeSysStyleMap& mapCache = PipeSysStyleCache(); + PipeSysStyleMap::const_iterator it = mapCache.find(sKey); + if (it != mapCache.end()) + { + st = it->second; + return true; + } + + PipeSysStyle stNew; + if (!QueryPipeSysStyle(pszSys, bCenter, stNew)) return false; + + mapCache[sKey] = stNew; + st = stNew; + return true; + } +} + int CoreTools::getColorByPipeSys(LPCTSTR sys, bool bCenter) { - CUIISQLiteServer db; - if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return 256; + PipeSysStyle st; + if (!GetPipeSysStyle(sys, bCenter, st)) return 256; - CString sTable(CoreTools::getCurrentPipeSysTblName()); - - CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线"); - CString sql; - sql.Format(_T("SELECT [COLOR] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys); - CString sClr(_T("256")); - db.GetSelData(sql, sClr); - return _ttoi(sClr); + return _ttoi(st.sColor); } AcDbObjectId CoreTools::getLtByPipeSys(LPCTSTR sys, bool bCenter) { AcDbObjectId id(AcDbObjectId::kNull); - CUIISQLiteServer db; - if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return id; - CString sTable(CoreTools::getCurrentPipeSysTblName()); - CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线"); - CString sql; - sql.Format(_T("SELECT [LINETYPE] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys); - CString sLt(_T("Continuous")); - db.GetSelData(sql, sLt); + PipeSysStyle st; + if (!GetPipeSysStyle(sys, bCenter, st)) return id; + + CString sLt(st.sLt); + if (sLt.IsEmpty()) sLt = _T("Continuous"); AcDbDatabase *pDb = acdbCurDwg(); if (!pDb) return id; @@ -4977,15 +5055,11 @@ AcDbObjectId CoreTools::getLtByPipeSys(LPCTSTR sys, bool bCenter) double CoreTools::getLwByPipeSys(LPCTSTR sys, bool bCenter) { - CUIISQLiteServer db; - if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return 0; + PipeSysStyle st; + if (!GetPipeSysStyle(sys, bCenter, st)) return 0; - CString sTable(CoreTools::getCurrentPipeSysTblName()); - CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线"); - CString sql; - sql.Format(_T("SELECT [LINEWIDTH] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys); - CString sLw(_T("0")); - db.GetSelData(sql, sLw); + CString sLw(st.sLw); + if (sLw.IsEmpty()) sLw = _T("0"); AecDbObjXDataMap xdata; if (KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xdata)) @@ -5007,15 +5081,12 @@ double CoreTools::getLwByPipeSys(LPCTSTR sys, bool bCenter) AcDbObjectId CoreTools::getLyByPipeSys(LPCTSTR sys, bool bCenter, bool bUpdate) { AcDbObjectId id; - CUIISQLiteServer db; - if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return id; - CString sTable(CoreTools::getCurrentPipeSysTblName()); - CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线"); - CString sql; - sql.Format(_T("SELECT [LAYNAME] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys); - CString sLy(_T("0")); - db.GetSelData(sql, sLy); + PipeSysStyle st; + if (!GetPipeSysStyle(sys, bCenter, st)) return id; + + CString sLy(st.sLy); + if (sLy.IsEmpty()) sLy = _T("0"); AcDbDatabase *pDb = acdbCurDwg(); if (!pDb) return id;