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()