array.from vs push

Benchmark created on


Setup

// Initialization code (in the setup block of jsperf)
var FakeNode = function(tagName) {
  this.tagName = tagName;
  this.childNodes = [];
  this.addChild = function(node) {
    this.childNodes.push(node);
    node.parent = this;
  };
  this.firstChild = function() {
    return this.childNodes[0] || null;
  };
  this.nextSibling = function() {
    const parent = this.parent;
    if (!parent) return null;
    const index = parent.childNodes.indexOf(this);
    return index !== -1 && index + 1 < parent.childNodes.length
      ? parent.childNodes[index + 1]
      : null;
  };
};

var generateFakeDOMNodes = function(totalNodes, childrenPerNode) {
  var nodes = [];
  for (var i = 0; i < totalNodes; i++) {
    var node = new FakeNode('Node' + i);
    for (var j = 0; j < childrenPerNode; j++) {
      var child = new FakeNode('Child' + i + '-' + j);
      node.addChild(child);
    }
    nodes.push(node);
  }
  return nodes;
};

var nodes = generateFakeDOMNodes(100, 100);

var getChildrenUsingArrayFrom = function(nodes, predicate) {
  return nodes.flatMap(function(node) {
    return Array.from(node.childNodes).filter(function(child) {
      return predicate ? predicate(child) : true;
    });
  });
};

var getChildrenUsingPush = function(nodes, predicate) {
  var allChildren = [];
  nodes.forEach(node => {
    var child = node.firstChild();
    while (child) {
      if (predicate ? predicate(child) : true) {
        allChildren.push(child);
      }
      child = child.nextSibling();
    }
  });
  return allChildren;
};

var samplePredicate = function(node) {
  return node.tagName.endsWith('0');
};

Test runner

Ready to run.

Testing in
TestOps/sec
Array.from
getChildrenUsingArrayFrom(nodes, samplePredicate);

ready
Push
getChildrenUsingPush(nodes, samplePredicate);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.