Open sigmaSd opened 1 month ago
Does the utility like this make more sense to such cases? https://github.com/fent/node-stream-equal
I'm not sure it feels weird to me that an assert equal doesn't work after a certain size, also the error is not helpful
It'd probably make sense to have a separate path for iterables and/or array-likes.
type Iter<T> = { [Symbol.iterator](): Iterator<T> };
type TypedArrayLike = Iter<number | bigint>;
function isTypedArray(x: unknown): x is TypedArrayLike {
return ArrayBuffer.isView(x) && Symbol.iterator in x;
}
function iterEqual<T>(a: Iter<T>, b: Iter<T>, eq: (a: T, b: T) => boolean): boolean {
if (a === b) return true;
if (a.constructor !== b.constructor) return false;
// @ts-expect-error - if no `length` prop we just check both undefined
if (a.length !== b.length) return false;
const aIter = a[Symbol.iterator]();
const bIter = b[Symbol.iterator]();
while (true) {
const aNext = aIter.next();
const bNext = bIter.next();
if (aNext.done !== bNext.done) return false;
if (!eq(aNext.value, bNext.value)) return false;
if (aNext.done) return true;
}
}
function typedArrayEqual(a: TypedArrayLike, b: TypedArrayLike): boolean {
return iterEqual(a, b, (a, b) => a === b);
}
const bytes = Deno.readFileSync(Deno.execPath());
const diffAtStart = bytes.slice();
++diffAtStart[0];
const diffAtEnd = bytes.slice();
++diffAtEnd[diffAtEnd.length - 1];
console.time();
// true
console.log(typedArrayEqual(bytes, bytes));
// 0ms
console.timeEnd();
console.time();
// true
console.log(typedArrayEqual(bytes, bytes.slice()));
// 3562ms
console.timeEnd();
console.time();
// false
console.log(typedArrayEqual(bytes, diffAtStart));
// 0ms
console.timeEnd();
console.time();
// false
console.log(typedArrayEqual(bytes, diffAtEnd));
// 3381ms
console.timeEnd();
console.time();
// false
console.log(typedArrayEqual(bytes, new Uint8Array(0)));
// 0ms
console.timeEnd();
deno -R a.ts