diff --git a/lib/core/LLVMCG/StructGen.py b/lib/core/LLVMCG/StructGen.py index ee3e01f..15ccbb3 100644 --- a/lib/core/LLVMCG/StructGen.py +++ b/lib/core/LLVMCG/StructGen.py @@ -303,6 +303,11 @@ class StructGenMixin: """ if Declared is None or Slot is None: return True + # 同一对象直接放行:llvmlite 的 Type.__eq__ 走类型键比较(profile: + # 本函数被 _generate_structs 调 54.2M 次,其中 types.py __eq__ 合计 ~30s) + # ⇒ 先做身份判定短路,等价且避免绝大多数 __eq__/str() 开销。 + if Declared is Slot: + return True if Declared == Slot or str(Declared) == str(Slot): return True _d_ptr: bool = isinstance(Declared, ir.PointerType) @@ -349,6 +354,14 @@ class StructGenMixin: return False def _generate_structs(self) -> None: + # 热路径局部化:profile 中本函数被调 35,240 次(cum 1893s),内部 + # SymbolTable.lookup 15.9M 次(16.7s)+ 真值判断触发的 __len__ 15.9M 次 + # (6.8s)⇒ 把 SymbolTable / lookup 提到局部,避免逐类重复属性查找。 + # 真值语义与 `if self.SymbolTable:` 逐字一致(SymbolTable 定义了 __len__, + # 空表为假);表在单次调用内只增不减,故提升到函数级等价。 + _symtab: Any = self.SymbolTable + _has_symtab: bool = bool(_symtab) + _sym_lookup: Any = _symtab.lookup if _symtab is not None else None all_classes: set[str] = set(self.class_methods.keys()) | set(self.class_members.keys()) preserved_structs: dict[str, ir.IdentifiedStructType] = {} @@ -367,8 +380,8 @@ class StructGenMixin: all_classes = set(self.class_methods.keys()) | set(self.class_members.keys()) for ClassName in all_classes: is_packed: bool = ClassName in self.class_packed - if self.SymbolTable: - Entry = self.SymbolTable.lookup(ClassName) + if _has_symtab and _sym_lookup is not None: + Entry = _sym_lookup(ClassName) if Entry and Entry.IsExceptionClass: continue # 注意:类名可能与 CEnum 成员名冲突(如 ASTKind.Module 枚举成员与 Module 类同名) @@ -484,8 +497,8 @@ class StructGenMixin: # Step 4: 创建最终的 structs 并设置正确的成员类型 for ClassName in all_classes: - if self.SymbolTable: - Entry = self.SymbolTable.lookup(ClassName) + if _has_symtab and _sym_lookup is not None: + Entry = _sym_lookup(ClassName) if Entry and Entry.IsExceptionClass: continue # 注意:类名可能与 CEnum 成员名冲突(如 ASTKind.Constant 枚举成员与 Constant 类同名)