88 lines
3.1 KiB
Python
88 lines
3.1 KiB
Python
from __future__ import annotations
|
||
from dataclasses import dataclass, field, asdict
|
||
import json
|
||
|
||
SCHEMA_VERSION = 4
|
||
|
||
|
||
@dataclass
|
||
class Environment:
|
||
python: str
|
||
platform: str
|
||
processor: str
|
||
timerResolution: float
|
||
|
||
|
||
@dataclass
|
||
class WallTime:
|
||
seconds: float
|
||
unit: str = "s"
|
||
|
||
|
||
@dataclass
|
||
class Calibration:
|
||
# v4 新增:cProfile 开销校准系数,用于把 instrumented wall-time 折算为干净耗时。
|
||
# 用户脚本只 exec 一次(单跑架构)的代价是 wall-time 带 cProfile 开销;启动期
|
||
# 用同一段 tight-loop 各跑一次(裸 vs 仪器化),ratio = instrumented / clean,
|
||
# 用户 wall_time = instrumented_user / ratio。
|
||
ratio: float
|
||
# 校准负载名:方便 debug 时看出是哪段负载产生的系数;目前固定为 "tight-loop"
|
||
workloadName: str = "tight-loop"
|
||
# 校准负载在 cProfile 下的耗时(秒)—— 透传给 UI 方便 debug
|
||
instrumentedWorkloadSec: float = 0.0
|
||
# 校准负载裸跑的耗时(秒)
|
||
cleanWorkloadSec: float = 0.0
|
||
|
||
|
||
@dataclass
|
||
class FunctionNode:
|
||
id: str # "file:line:name"
|
||
file: str
|
||
line: int
|
||
name: str
|
||
cumtime: float
|
||
tottime: float
|
||
ncalls: int
|
||
percallTot: float
|
||
# 顶层模块名(用于 scope=all 时的 UI 分类):
|
||
# "<user>" 用户脚本 / "json" / "numpy" / "<frozen>" 等。
|
||
# 提取逻辑见 engine/structure._top_module;这一层做归类,
|
||
# 让 UI 不必重新解析文件路径(路径 normalize 在 OS 间不一致)。
|
||
module: str = ""
|
||
# 帧来源(v3 新增;用于 UI 按 origin 分组):
|
||
# "user" 用户脚本 / "stdlib" 标准库 / "third_party" 第三方包 /
|
||
# "builtin" 内置(C 实现的 builtin) / "frozen" frozen importlib 等 /
|
||
# "other" 兜底(未匹配任何已知来源,例如奇怪的 <string> 帧)
|
||
#
|
||
# 优先用 sys.stdlib_module_names 校准(3.10+),降级用路径启发式:
|
||
# /Lib/ 或 /lib/pythonX.Y/ → stdlib;含 site-packages/dist-packages → third_party。
|
||
# 推导逻辑见 engine/structure._classify_origin。
|
||
origin: str = ""
|
||
|
||
|
||
@dataclass
|
||
class FlameNode:
|
||
name: str
|
||
value: float
|
||
children: list = field(default_factory=list)
|
||
|
||
|
||
@dataclass
|
||
class AnalysisResult:
|
||
schemaVersion: int
|
||
environment: Environment
|
||
config: dict
|
||
status: str # ok|syntax_error|runtime_error|timeout
|
||
error: dict | None
|
||
wallTime: WallTime | None
|
||
functions: list
|
||
flame: FlameNode | None
|
||
# v4 新增:ok 状态下必有;非 ok(语法错 / 运行时错 / 超时)下为 None。
|
||
# 见 Calibration 字段注释 —— 折算 wallTime 时需要,存到 result 里给 UI 看。
|
||
calibration: Calibration | None = None
|
||
|
||
def to_json(self) -> str:
|
||
# ensure_ascii=True(默认):在 GBK locale / 没设 PYTHONUTF8 的环境下
|
||
# stdout 不是合法 UTF-8,UI 解析会挂。转义成纯 ASCII 后逐字节一致,
|
||
# JSON.parse 原生还原。主进程仍然会设那两个环境变量,这里是纵深防御。
|
||
return json.dumps(asdict(self), ensure_ascii=True) |