diff --git a/src/playground/benchmark.css b/src/playground/benchmark.css index 07068f59b..746c173a8 100644 --- a/src/playground/benchmark.css +++ b/src/playground/benchmark.css @@ -11,16 +11,42 @@ p { left: 450px; } } +.share { + display: none; +} +.share label { + cursor: pointer; +} +.share[href] { + display: inline; +} + +.render .profile-tables { + position: static; + left: 0; +} +.render .description { + display: none; +} +.render .run-push { + display: none; +} #scratch-stage { border: 5px solid black; display: block; width: 400px; height: 300px; } +.render #scratch-stage { + display: none; +} .loading label, .profile-count label{ width: 15em; display: inline-block; } +.render .loading { + display: none; +} .profile-tables table { margin: 30px 0 30px 0px; } diff --git a/src/playground/benchmark.js b/src/playground/benchmark.js index bca3e0532..3c2963979 100644 --- a/src/playground/benchmark.js +++ b/src/playground/benchmark.js @@ -13,12 +13,20 @@ document.querySelector('.run') location.reload(); }, false); +const setShareLink = function (json) { + document.querySelector('.share') + .href = `#view/${btoa(JSON.stringify(json))}`; + document.querySelectorAll('.share')[1] + .href = `suite.html`; +}; + const loadProject = function () { let id = location.hash.substring(1).split(',')[0]; if (id.length < 1 || !isFinite(id)) { id = projectInput.value; } Scratch.vm.downloadProjectId(id); + return id; }; /** @@ -221,6 +229,13 @@ const frameOrder = [ 'Runtime._step' ]; +const trackSlowFrames = [ + 'Sequencer.stepThreads', + 'Sequencer.stepThreads#inner', + 'Sequencer.stepThread', + 'execute' +]; + class FramesTable extends StatTable { constructor (options) { super(options); @@ -241,12 +256,7 @@ class FramesTable extends StatTable { } isSlow (key, frame) { - return ([ - 'Sequencer.stepThreads', - 'Sequencer.stepThreads#inner', - 'Sequencer.stepThread', - 'execute' - ].indexOf(key) > 0 && + return (trackSlowFrames.indexOf(key) > 0 && frame.selfTime / frame.totalTime > SLOW); } } @@ -346,7 +356,7 @@ class ProfilerRun { } run () { - loadProject(); + this.projectId = loadProject(); window.parent.postMessage({ type: 'BENCH_MESSAGE_LOADING' @@ -378,12 +388,49 @@ class ProfilerRun { frames: this.frames.frames, opcodes: this.opcodes.opcodes }, '*'); + + setShareLink({ + fixture: { + projectId: this.projectId, + warmUpTime: this.warmUpTime, + recordingTime: this.maxRecordedTime + }, + frames: this.frames.frames, + opcodes: this.opcodes.opcodes + }); }, 100 + this.warmUpTime + this.maxRecordedTime); }); } + + render (json) { + const {fixture} = json; + document.querySelector('[type=text]').value = [ + fixture.projectId, + fixture.warmUpTime, + fixture.recordingTime + ].join(','); + + this.frames.frames = json.frames.map( + frame => Object.assign(new StatView(), frame, { + name: this.profiler.nameById(this.profiler.idByName(frame.name)) + }) + ); + + this.opcodes.opcodes = {}; + Object.entries(json.opcodes).forEach(([opcode, data]) => { + this.opcodes.opcodes[opcode] = Object.assign(new StatView(), data); + }); + + this.frameTable.render(); + this.opcodeTable.render(); + } } -window.onload = function () { +/** + * Run the benchmark with given parameters in the location's hash field or + * using defaults. + */ +const runBenchmark = function () { // Lots of global variables to make debugging easier // Instantiate the VM. const vm = new window.VirtualMachine(); @@ -493,3 +540,29 @@ window.onload = function () { // Run threads vm.start(); }; + +/** + * Render previously run benchmark data. + * @param {object} json data from a previous benchmark run. + */ +const renderBenchmarkData = function (json) { + const vm = new window.VirtualMachine(); + new ProfilerRun({vm}).render(json); + setShareLink(json); +}; + +window.onload = function () { + if (location.hash.substring(1).startsWith('view')) { + document.body.className = 'render'; + const data = location.hash.substring(6); + const frozen = atob(data); + const json = JSON.parse(frozen); + renderBenchmarkData(json); + } else { + runBenchmark(); + } +}; + +window.onhashchange = function () { + location.reload(); +}; diff --git a/src/playground/index.html b/src/playground/index.html index 81ba4f577..9a0fcfbe7 100644 --- a/src/playground/index.html +++ b/src/playground/index.html @@ -8,19 +8,21 @@

Scratch VM Benchmark

-

+

Welcome to the scratch-vm benchmark. This tool helps you profile a scratch project. When you load the page, it: -

    +
    1. loads the default project and enables turbo mode
    2. runs the project for 4 seconds to warm up
    3. profiles for 6 seconds
    4. stops and reports

    - - -

    +

    + + +
    +

    Try a different project, like `130041250`

    @@ -43,6 +45,14 @@ ... +
    + +
    + +
    + +
    +