function mainThread() {
  var maxDepth = Math.max(6, Number(arg[0] || 16));

  var stretchDepth = maxDepth + 1;
  var check = itemCheck(bottomUpTree(stretchDepth));
  log.console(`stretch tree of depth ${stretchDepth}\t check: ${check}`);

  var longLivedTree = bottomUpTree(maxDepth);

  for (let depth = 4; depth <= maxDepth; depth += 2) {
    var iterations = 1 << maxDepth - depth + 4;
    work(iterations, depth);
  }

  log.console(`long lived tree of depth ${maxDepth}\t check: ${itemCheck(longLivedTree)}`);
}

function work(iterations, depth) {
  let check = 0;
  for (let i = 0; i < iterations; i++)
    check += itemCheck(bottomUpTree(depth));
  log.console(`${iterations}\t trees of depth ${depth}\t check: ${check}`);
}

function TreeNode(left, right) {
    return {left, right};
}

function itemCheck(node) {
  if (node.left == null)
    return 1;
  return 1 + itemCheck(node.left) + itemCheck(node.right);
}

function bottomUpTree(depth) {
  return depth > 0
    ? new TreeNode(bottomUpTree(depth - 1), bottomUpTree(depth - 1))
    : new TreeNode(null, null);
}

mainThread()

$_.stop()