Files
Python-Profiler-Visualizer/engine/schema.py
2026-09-12 14:19:56 +08:00

87 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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-8UI 解析会挂。转义成纯 ASCII 后逐字节一致,
# JSON.parse 原生还原。主进程仍然会设那两个环境变量,这里是纵深防御。
return json.dumps(asdict(self), ensure_ascii=True)