Files

93 lines
4.2 KiB
Python

#!/usr/bin/env python3
"""Profiler checks: headers, summaries/comparison, and unchanged pixels/simulation with clocks on."""
import contextlib
import io
import math
import copy
from urllib.request import urlopen
from perf import ROOT, quantiles, measurements, report
from browser import launch, consume_gpu_option
from use_venv import ensure_playwright
def main():
q = quantiles([4, 1, 3, 2])
assert all(math.isclose(q[k], v) for k, v in [('p50', 2.5), ('p95', 3.85), ('p99', 3.97)])
assert dict(measurements({'calls': 10, 'total_ms': 3, 'marks_ms': {'color': 2}})) == {
'/total_ms': 3, '/marks_ms/color': 2}
data = {'machine': {'renderer': 'test', 'cores': 1, 'crossOriginIsolated': True, 'webgpu': True},
'options': {'viewport': [1920, 1080], 'world': [2048, 1024]}, 'elapsed_seconds': 1,
'scenes': {'factory': {'views': {}, 'runs': {}, 'sim': {'total_ms': 1, 'rest_ms': 0,
'steps': {}, 'start': {'awake': 1, 'hot': 1}, 'end': {'awake': 1, 'hot': 1, 'chunks': 2}}}}}
newer = copy.deepcopy(data)
newer['scenes']['factory']['sim']['total_ms'] = 1.2
out = io.StringIO()
with contextlib.redirect_stdout(out):
report(newer, data)
assert '/factory/sim/total_ms: +20.0% REGRESSION' in out.getvalue()
assert 'n/a (baseline zero)' in out.getvalue()
ensure_playwright()
consume_gpu_option()
with launch() as (browser, pg, url):
with urlopen(url) as response:
assert response.headers['Cross-Origin-Opener-Policy'] == 'same-origin'
assert response.headers['Cross-Origin-Embedder-Policy'] == 'require-corp'
response.read()
errors = []
pg.on('pageerror', lambda e: errors.append(str(e)))
pg.add_init_script('window.requestAnimationFrame = () => 0;')
pg.goto(url)
pg.evaluate('CAPS_CHECK')
pg.add_script_tag(content=(ROOT / 'tools/perf-scenes.js').read_text())
assert pg.evaluate('crossOriginIsolated')
# Compare to the unwrapped functions, and hash the byte representation of all grid state.
hashes = pg.evaluate('''() => {
const hash = () => {
let h = 2166136261;
for (const a of [mat, temp, flags, stamp, part, awake, hot])
for (const b of new Uint8Array(a.buffer, a.byteOffset, a.byteLength)) h = Math.imul(h ^ b, 16777619);
return h >>> 0;
};
const results = [];
for (const enabled of [false, true]) {
SET.showPerf = enabled;
generateWorld(424242, 640, 384, null);
for (let k = 0; k < 240; k++) simTick();
results.push(hash());
}
return results;
}''')
assert hashes[0] == hashes[1], hashes
pg.evaluate("perfScene('factory', 1024, 640)")
for look in ['pixel', 'smooth']:
identical = pg.evaluate('''look => {
perfView(look, 6);
const now = performance.now.bind(performance);
performance.now = () => 5000;
R.rain = rainAt(Math.max(0, Math.min(W - 1, Math.floor(R.camX + R.bw / 2))));
try {
PERF_MARKS = false; drawWorld(); const a = worldPixelContext().canvas.toDataURL();
PERF_MARKS = true; drawWorld(); const b = worldPixelContext().canvas.toDataURL();
return a === b;
} finally { PERF_MARKS = false; performance.now = now; }
}''', look)
assert identical, f'{look}: marks changed pixels'
pg.evaluate('''() => {
SET.showPerf = true; GAME.paused = false;
for (let k = 0; k < 30; k++) frame(lastT + 1000 / 60);
GAME.paused = true;
$('cards').innerHTML = '';
document.querySelectorAll('.toast').forEach(e => e.remove());
}''')
text = pg.locator('#perf').inner_text()
assert all(word in text for word in ['world', 'light', 'overlays', 'move', 'heat', 'rest']), text
pg.screenshot(path=f'/tmp/t88-perf-{look}.png')
assert not errors, errors
browser.close()
print('PASS headers, quantiles, comparison, deterministic simulation and pixel/smooth image parity; readout screenshots saved')
if __name__ == '__main__':
main()