check if 2 arrays have the same elements (order doesnt matter) (v5)

Revision 5 of this benchmark created on


Description

not only is most code out there unoptimized, but i've also seen syntactically horrible and even wrong code, so i'm searching for the best solution in this perf (dont expect readable code, i'm aiming more for performance here)

Setup

let arr1 = [];
let arr2 = [];

// adds random 100 numbers to the end of arr1 and to the start of arr2
for(let i = 0;i < 100;i++) {
	let number = Math.floor(Math.random() * 100);
	arr1.push(number);
	arr2.unshift(number);
}

Test runner

Ready to run.

Testing in
TestOps/sec
naive imperative solution
let result = (() => {
	if(arr1.length !== arr2.length) return false;
	let arr2_indices = new Set();
	for(let i = 0;i < arr1.length;i++) {
        let found_match = false;
		for(let j = 0;j < arr2.length;j++) {
			if(arr1[i] === arr2[j] && !arr2_indices.has(j)) {
                arr2_indices.add(j);
                found_match = true;
                break;
			}
		}
        if(!found_match) return false;
	}
    return true;
})();
if(result !== true) throw Error(`naive imperative solution didn't return true\n\narr1=${arr1}\n\n\n\n\n\n\n\n\n\narr2=${arr2}`);
ready
solution using Map (1)
let result = (() => {
	if(arr1.length !== arr2.length) return false;
	let arr2_elementCount = new Map();
	for(let i = 0;i < arr2.length;i++) {
		// ~~x returns 0 if x is undefined and x if x is a number
		arr2_elementCount.set(arr2[i], (~~arr2_elementCount.get(arr2[i])) + 1);
	}
    for(let i = 0;i < arr1.length;i++) {
        let elementCount = ~~arr2_elementCount.get(arr1[i]);
        if(elementCount ===
         0) return false;
        arr2_elementCount.set(arr1[i], elementCount - 1);
    }
    return true;
})();
if(result !== true) throw Error(`solution using Map (1) didn't return true\n\narr1=${arr1}\n\n\n\n\n\n\n\n\n\narr2=${arr2}`);
ready
solution using Map (2)
let result = (() => {
	if(arr1.length !== arr2.length) return false;
	let arr1_elementCount = new Map();
	let arr2_elementCount = new Map();
	for(let i = 0;i < arr1.length;i++) {
		// ~~x returns 0 if x is undefined and x if x is a number
		arr1_elementCount.set(arr1[i], (~~arr1_elementCount.get(arr1[i])) + 1);
		arr2_elementCount.set(arr2[i], (~~arr2_elementCount.get(arr2[i])) + 1);
	}
	arr1_elementCount.forEach((value, key) => {
		if(arr2_elementCount.get(key) !== value) return false;
	});
	return true;
})();
if(result !== true) throw Error(`solution using Map (3) didn't return true\n\narr1=${arr1}\n\n\n\n\n\n\n\n\n\narr2=${arr2}`);
ready

Revisions

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