UNPKG

neutrinoscript

Version:
328 lines (289 loc) 8.86 kB
<html> <head> <title>LLJS : Low-Level JavaScript</title> <link rel="stylesheet" type="text/css" href="css/screen.css"> <link rel="stylesheet" href="vendor/cm/lib/codemirror.css"> </head> <body> <a href="https://github.com/mbebenita/LLJS"><img style="position: absolute; top: 0; right: 0; border: 0;" src="images/fork.png" alt="Fork me on GitHub"></a> <a href="http://mozilla.org"><img width="118" height="68" style="position: absolute; top: 0; left: 50; border: 0;" src="images/mozilla.png" alt="Mozilla"></a> <br> <div class="container"> <h2>K&R Malloc vs. JS Object Allocation</h2> <canvas id="canvas-latency" width="640" height="100"></canvas> <br><br> <canvas id="canvas" width="640" height="640"></canvas> <script> var latency = (function () { var ctx = document.getElementById('canvas-latency').getContext('2d'); var width = 640; var height = 100; var sampleWidth = 4 var sampleCount = width / (sampleWidth + 1); var last = null; var samples = []; var max = 0; function computeStandardDeviation(x) { var a = 0, b = 0, n = x.length; for (var i = 0; i < n; i++) { a += x[i] * x[i]; b += x[i]; } return Math.sqrt(a / n - (b / n) * (b / n)); } return { tick: function () { var curr = new Date(); if (last) { if (samples.length > sampleCount) { samples.shift(); } samples.push(curr - last); ctx.clearRect(0, 0, 640, 100); var sum = 0; for (var i = 0; i < samples.length; i++) { sum += samples[i]; max = Math.max(max, samples[i]); } var avg = sum / samples.length; for (var i = 0; i < samples.length; i++) { var scaledSample = (samples[i] / max); ctx.fillRect(i * (sampleWidth + 1), 100, sampleWidth, - scaledSample * (height - 30)); } ctx.font = "Bold 10pt Verdana"; ctx.fillText("fps: " + (1000 / avg).toFixed(2) + ", std: " + computeStandardDeviation(samples).toFixed(2), 0, 25); } last = curr; } }; })(); var cancelAnimationFrame = ( function() { return window.cancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || clearTimeout } )(); var requestAnimationFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback, /* DOMElement */ element){ return window.setTimeout(callback, 1000 / 60); }; })(); </script> <pre class="example"> const int n = 250000; // Number of object allocations. const int m = 300; // Number of balls. function drawHook() { benchObject(); // benchStruct(); } extern document, window, Math, Date, trace, latency, cancelAnimationFrame, requestAnimationFrame; let balls = []; let radius = 10, width = 640, height = 640; for (let i = 0; i < m; i++) { let dx = 0.5 - Math.random(); let dy = 0.5 - Math.random(); balls.push({x: width / 2, y: height / 2, dx: dx, dy: dy, radius: 5 + Math.random() * 5}); } let ctx = document.getElementById('canvas').getContext('2d'); struct Node { Node *next; int val; double pad1, pad2, pad3, pad4; }; function ObjNode() { this.next = null; this.val = 0; this.pad1 = 0; this.pad2 = 0; this.pad3 = 0; this.pad4 = 0; } function benchStruct() { let Node *head; for (let int i = 0; i < n; ++i) { let Node *prev = head; head = new Node; head->next = prev; head->val = i; } let double sum = 0; for (let int i = 0; i < n; ++i) { let Node *prev = head; sum += head->val; head = head->next; delete prev; } } function benchObject() { let head; for (let i = 0; i < n; ++i) { let prev = head; head = new ObjNode(); head.next = prev; head.val = i; } let sum = 0; for (let i = 0; i < n; ++i) { sum += head.val; head = head.next; } } let last = new Date(); let request; function draw() { latency.tick(); ctx.clearRect(0, 0, width, height); drawHook(); let curr = new Date(); let elapsed = (curr - last) / 10; last = curr; for (let i = 0; i < balls.length; i++) { let ball = balls[i]; let dx = ball.dx * elapsed; let dy = ball.dy * elapsed; let nx = ball.x + dx; let ny = ball.y + dy; if (nx < ball.radius || nx > width - ball.radius) { ball.dx *= -1; dx *= -1; } if (ny < ball.radius || ny > height - ball.radius) { ball.dy *= -1; dy *= -1; } ball.x += dx; ball.y += dy; ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fill(); } request = requestAnimationFrame(draw); } if (request) { cancelAnimationFrame(request); } draw(); </pre> </div> <script src="vendor/cm/lib/codemirror.js"></script> <script src="vendor/cm/mode/javascript/javascript.js"></script> <script src="vendor/jquery-1.7.2.min.js"></script> <script src="lljs/estransform.js"></script> <script src="lljs/types.js"></script> <script src="lljs/util.js"></script> <script src="lljs/scope.js"></script> <script src="lljs/esprima.js"></script> <script src="lljs/escodegen.js"></script> <script src="lljs/compiler.js"></script> <script src="lljs/memcheck.js"></script> <script src="lljs/memory.js"></script> <script src="lljs/ljc.js"></script> <script> var id = 0; $('.example').replaceWith(function() { var src = this.innerHTML; var lineCount = src.split("\n").length; return '<table class="example"><tr><td><textarea id="ex:' + id + ':source" class="jcCode" rows="' + lineCount + '" spellcheck="false">' + src + '</textarea></td><td valign="top"><pre id="ex:' + id++ + ':result" class="jcResult"></pre></td></tr></table>' }); var lastMarker; function compileExample(ex) { if (lastMarker) { this.clearMarker(lastMarker); } var number = ex.split(":")[1]; var result = document.getElementById("ex:" + number + ":result"); try { var name; if (Number(number) === id - 1) { name = "memory"; } else { name = "ex" + number; } result.innerHTML = LJC.compile(name, name, this.getValue(), { bare: true }); } catch (x) { result.innerHTML = x.message; if (x.lineNumber) { lastMarker = this.setMarker(x.lineNumber - 1, "<span style=\"color: #900\">x</span> %N%"); } } } var Timer = (function () { function timer() { this.name = null; this.start = null; } timer.prototype.begin = function (name) { if (this.start) { if (this.name) { trace("Timer: " + (new Date() - this.start) + " ms: " + this.name); } else { trace("Timer: " + (new Date() - this.start) + " ms."); } } this.start = new Date(); this.name = name; }; return timer; })(); var timer; var trace; function require(name) { if (name === "memory") { return memory; } return null; } function executeExample(id) { var number = id.split(":")[1]; var result = document.getElementById("ex:" + number + ":result"); try { memory.reset(); timer = new Timer(); result.innerHTML = ""; trace = function (x) { result.innerHTML += x + "\n"; }; start = new Date(); var code = LJC.compile("ex" + number, "ex" + number, this.getValue(), {}); result.innerHTML += "Compiled in: " + (new Date() - start) + " ms\n"; result.innerHTML += "-----------------------------------------------------\n"; start = new Date(); new Function(code)(); timer.begin(null); result.innerHTML += "-----------------------------------------------------\n"; result.innerHTML += "Executed in : " + (new Date() - start) + " ms."; } catch (x) { result.innerHTML = x.message; } } $('.jcCode').each(function() { var id = this.id; var cm = CodeMirror.fromTextArea(this, { tabSize: 2, lineNumbers: true, gutter: true, onChange: function () { compileExample.call(cm, id); }, extraKeys: { "Ctrl-Enter": function () { executeExample.call(cm, id); }, "Cmd-Enter": function () { executeExample.call(cm, id); } } }); compileExample.call(cm, id); }); </script> </body> </html>