Fork me on GitHub Mozilla

K&R Malloc vs. JS Object Allocation




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();