From c62153a685c73d6163b795be834e4b2922540a90 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 22 Aug 2026 06:04:38 +0800 Subject: [PATCH] =?UTF-8?q?perf(tpc):=20import=20=E7=83=AD=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E4=BC=98=E5=8C=96=E2=80=94=E2=80=94walk=20=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E7=BC=93=E5=AD=98=20+=20DebugPrint=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=83=B0=E6=80=A7=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - import 兜底查找(_EmitModuleDeclarationsLlvm)每次解析失败都 os.walk 递归扫描 includes/工程目录,且多级模块名与 basename 永不匹配纯浪费:改为多级跳过 + 目录 walk 结果类级缓存(编译进程内目录不变) - DebugPrint 调用点(HandlesTypeMerge 类型查询热路径)无条件构造 f-string 参数(含昂贵的 ast.dump),即使 DebugFile 未设置也执行:改为 getattr(DebugFile) 防护后才构造(单文件 profile:_io.open 1253 次 1.76s + DebugPrint cum 2.24s) --- lib/core/Handles/HandlesImports.py | 31 ++++++++++++++++++++-------- lib/core/Handles/HandlesTypeMerge.py | 7 +++++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/core/Handles/HandlesImports.py b/lib/core/Handles/HandlesImports.py index 488285a..126941b 100644 --- a/lib/core/Handles/HandlesImports.py +++ b/lib/core/Handles/HandlesImports.py @@ -22,6 +22,10 @@ class ImportHandle(BaseHandle): _pyi_cache = {} _pyi_cache_dir = None _project_root_cache = None + # 目录 os.walk 结果缓存(import 失败兜底查找用):目录 -> [(root, files)]。 + # 编译进程内 SearchDirsForSubmodule(includes/LibraryPaths/工程目录)内容不变, + # 避免每次 import 解析失败都全量递归扫描目录树(PROF:import 热路径高频调用)。 + _walk_cache: dict[str, list[tuple[str, list[str]]]] = {} # 类级 stub 索引:class_name -> list of (full_name, struct_body, file_sha1, from_output) # 一次扫描所有 .stub.ll 文件构建索引,避免 _TryLoadStructFromStub 每次调用都全量扫描 # (原 609 次调用 × ~100 stub 文件 × ~50 行 = 5.5M 正则匹配 → 一次扫描 ~5000 匹配) @@ -647,18 +651,27 @@ class ImportHandle(BaseHandle): SearchFromDirs = [os.getcwd()] SearchDirsForSubmodule = SearchFromDirs + [os.path.join(TransPyCRoot, 'includes'), os.path.join(TransPyCRoot, 'lib', 'includes')] + list(self.Trans.LibraryPaths) for SearchPath in SearchDirsForSubmodule: - if os.path.isdir(SearchPath): - for root, dirs, files in os.walk(SearchPath): - if '__pycache__' in root: - continue - for src_ext in ('.vp', '.py', '.vpi', '.pyi'): - if module_name + src_ext in files: - FullModulePath = os.path.join(root, module_name + src_ext) - break - if FullModulePath: + if not os.path.isdir(SearchPath): + continue + # 多级模块名(含 '.')与 basename 文件列表(files 无路径) + # 永不匹配 `module_name + ext in files`,walk 纯属浪费,跳过。 + if '.' in module_name: + continue + # 目录 walk 结果缓存(编译进程内目录内容不变):import 热路径 + # 高频解析失败时避免重复递归扫描 includes/工程目录(PROF 热点) + walk_entries: list[tuple[str, list[str]]] = ImportHandle._walk_cache.get(SearchPath) + if walk_entries is None: + walk_entries = [(r, fs) for r, dirs, fs in os.walk(SearchPath) if '__pycache__' not in r] + ImportHandle._walk_cache[SearchPath] = walk_entries + for root, files in walk_entries: + for src_ext in ('.vp', '.py', '.vpi', '.pyi'): + if module_name + src_ext in files: + FullModulePath = os.path.join(root, module_name + src_ext) break if FullModulePath: break + if FullModulePath: + break # fail-fast:模块在所有来源都"完全未知"时立即报错,暴露 import 路径错误 # (如目录重组后未更新的旧路径)。之前静默容忍导致引用方跨模块 mangled # 前缀 fallback 当前模块 sha1,链接期才暴露 undefined symbol。 diff --git a/lib/core/Handles/HandlesTypeMerge.py b/lib/core/Handles/HandlesTypeMerge.py index 4fe6357..91997eb 100644 --- a/lib/core/Handles/HandlesTypeMerge.py +++ b/lib/core/Handles/HandlesTypeMerge.py @@ -37,7 +37,9 @@ class HandlesTypeMerge(BaseHandle): """鍐呴儴鏂规硶锛岃繑鍥?CTypeInfo""" LineNum = getattr(Node, 'lineno', None) - self.Trans.DebugPrint(f"[GetCTypeInfo] Node type: {type(Node).__name__}, dump: {ast.dump(Node)[:60]}...") + if getattr(self.Trans, 'DebugFile', None): + # 仅 debug 模式构造参数(ast.dump 昂贵,非 debug 时无条件执行是隐藏热点) + self.Trans.DebugPrint(f"[GetCTypeInfo] Node type: {type(Node).__name__}, dump: {ast.dump(Node)[:60]}...") if isinstance(Node, ast.Constant): TypeName = Node.value @@ -152,7 +154,8 @@ class HandlesTypeMerge(BaseHandle): if resolved: ModulePath = resolved - self.Trans.DebugPrint(f"[GetCTypeInfo-Attribute] 查询: '{TypeName}' ModulePath: {ModulePath}") + if getattr(self.Trans, 'DebugFile', None): + self.Trans.DebugPrint(f"[GetCTypeInfo-Attribute] 查询: '{TypeName}' ModulePath: {ModulePath}") if ModulePath == 't' and TypeName == 'State': Info = CTypeInfo()