Google Chrome のプロファイラJSON
古めの資料
ちなみにああいうグラフは Flame Graph と言うらしい。
例
code:sample.json
[
{ "pid":1, "tid":1, "ts":87705, "dur":956189, "ph":"X", "name":"Jambase", "args":{ } },
{ "pid":1, "tid":1, "ts":128154, "dur":75867, "ph":"X", "name":"1", "args":{ } },
{ "pid":"2a", "tid":1, "ts":546867, "dur":121564, "ph":"X", "name":"1", "args":{ "foo": "bar", "hoge":1 } },
{ "pid":"2a", "tid":2, "ts":546867, "ph":"B", "name":"2", "args":{ "with":"BE" } },
{ "pid":"2a", "tid":2, "ts":856867, "ph":"E", "name": "2" }
]
pid,tidは文字列でもよさそう。tsはマイクロ秒。
B/Eは前述の資料ではEにnameは不要ぽいが、実際には必要っぽい
B/Eは時系列順である必要がある。b/eやXは不要。
Pythonでの簡易実装
code:profiler.py
import contextlib
import json
import os
import time
from pathlib import Path
from typing import Union
class Profiler:
self.path = path
self.buf = []
self.pid = pid if pid is not None else os.getpid()
self.tid = tid
@contextlib.contextmanager
def duration(self, name: str, **args):
st = time.time()
yield None
self.buf.append({"ph": "X", "ts": st * 1000000, "dur": (time.time() - st) * 1000000, "name": name, "args": args})
def instant(self, name: str, **args):
self.buf.append({"ph": "I", "ts": time.time() * 1000000, "name": name, "args": args})
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
with open(self.path, "w", encoding="utf-8") as fp: