Comparing Some Bitwise Operations and Similar Tests (v2)

Revision 2 of this benchmark created on


Description

Setup

const isN = [
  false, true, false,
  true,        true,
  false, true, false,
];
function run (test) {
	let guys = 0;
	for (let y = 0; y < 100; y++) {
		for (let x = 0; x < 100; x++) {
			for (let i = 0; i < 8; i++) {
				const n = isN[i];
				if (Boolean(test(i)) !== n) {
					throw new Error(`wrong: ${test(i)} !== ${n} @ ${x},${y}`);
				}
				guys++;
			}
		}
	}
	console.log(`tested ${guys} guys ok`);
}

// share the load mr frodo
const LUT = [0, 1, 0, 1, 1, 0, 1, 0];
const BYEAHS = new Set([1,3,4,6])
const MAP = new Map([
    [0, false],
    [1, true],
    [2, false],
    [3, true],
    [4, true],
    [5, false],
    [6, true],
    [7, false],
]);

const OBJ = {
	0: false,
	1: true,
	2: false,
	3: true,
	4: true,
	5: false,
	6: true,
	7: false,
};

const NPO = Object.create(null, {
	0: { value: false },
	1: { value: true },
	2: { value: false },
	3: { value: true },
	4: { value: true },
	5: { value: false },
	6: { value: true },
	7: { value: false },
})



const GuyEvaluatorFactory = (() => {
	class GuyError extends Error {
	name = 'GuyError'
	constructor () {
		super('what am i doing with my life');
	}
  }
  const _GuyEvaluatorImpl = class {
	/** @prop - try to cache instances to help performance? TODO - hook up debug tooling... 
	*/
	static _instances = [];
	/**
	 * @prop 0|1|2|3|4|5|6|7 x: the number whose guy status is being memoized
	 * @prop boolean isGuy: whether x is a guy... TODO - we really need typescript, this is not maintainable
	 */
	/**
	 * @param boolean isGuy: whether the instance being created is a guy
	 */
	constructor (isGuy) {
	  if (isGuy == null)
	    throw new GuyError();
      this.isGuy = isGuy;
	}
	/**
	 * @param ok im tired of the joke now
	 * @returns GuyEvaluator
	 */
	static getOrCreateGuyEvaluator (x, isGuy) {
	  return this._instances[x] ??= new this(isGuy)
	}
	
	static testGuy(x) {
		return this
		  .getOrCreateGuyEvaluator(x).isGuy;
	}
	
	static initSingleton() {
		this.getOrCreateGuyEvaluator(0, false);
		this.getOrCreateGuyEvaluator(1, true);
		this.getOrCreateGuyEvaluator(2, false);
		this.getOrCreateGuyEvaluator(3, true);
		this.getOrCreateGuyEvaluator(4, true);
		this.getOrCreateGuyEvaluator(5, false);
		this.getOrCreateGuyEvaluator(6, true);
		this.getOrCreateGuyEvaluator(7, false);
		return this;	
	}
  }
  return _GuyEvaluatorImpl
    .initSingleton()
    .testGuy
    .bind(_GuyEvaluatorImpl);
})();

Test runner

Ready to run.

Testing in
TestOps/sec
chained boolean `||` (reference implementation)
run(
  x => x === 1 || x === 3 || x === 4 || x === 6
);
ready
switch
run(x => {
	switch (x) {
		case 1:
		case 3:
		case 4:
		case 6:
		  return true;
		default:
		  return false;
	}
})
ready
smallbrain test 1
run(x => x < 4 ? (x & 1) : !(x & 1));
ready
1st answer
run(x =>
  1 << x & (1 << 1 | 1 << 3 | 1 << 4 | 1 << 6)
);
ready
2nd answer
run(x => ((x >>> 2) ^ x) & 1)
ready
3rd answer
run(x => (x & 1) !== (x >>> 2));
ready
LUT
run(x => LUT[x]);
ready
set
run(x => BYEAHS.has(x));
ready
object, lol

run(x => OBJ[x])
ready
TRYHARD object
run(x => NPO[x]);
ready
map?
run(x => MAP.get(x));
ready
Enterprise guy solution
run(GuyEvaluatorFactory)
ready
the humble if herd
run(x => {
	if (x === 1) return true;
	else if (x === 3) return true;
	else if (x === 4) return true;
	else if (x === 6) return true;
	else return false;
})
ready

Revisions

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