Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(object-hash): faster circular checking by using map #34

Merged
merged 1 commit into from Apr 22, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 10 additions & 8 deletions src/object-hash.ts
Expand Up @@ -70,7 +70,7 @@ export function objectHash(object: any, options: HashOptions = {}): string {

function createHasher(options: HashOptions) {
let buff = "";
let context = [];
let context = new Map();
const write = (str: string) => {
buff += str;
};
Expand Down Expand Up @@ -111,10 +111,10 @@ function createHasher(options: HashOptions) {

let objectNumber = null;

if ((objectNumber = context.indexOf(object)) >= 0) {
if ((objectNumber = context.get(object)) !== undefined) {
return this.dispatch("[CIRCULAR:" + objectNumber + "]");
} else {
context.push(object);
context.set(object, context.size);
}

if (
Expand Down Expand Up @@ -182,16 +182,18 @@ function createHasher(options: HashOptions) {
// The unordered case is a little more complicated: since there is no canonical ordering on objects,
// i.e. {a:1} < {a:2} and {a:1} > {a:2} are both false,
// We first serialize each entry using a PassThrough stream before sorting.
// also: we can’t use the same context array for all entries since the order of hashing should *not* matter. instead,
// we keep track of the additions to a copy of the context array and add all of them to the global context array when we’re done
const contextAdditions = [];
// also: we can’t use the same context for all entries since the order of hashing should *not* matter. instead,
// we keep track of the additions to a copy of the context and add all of them to the global context when we’re done
const contextAdditions = new Map();
const entries = arr.map((entry) => {
const hasher = createHasher(options);
hasher.dispatch(entry);
contextAdditions.push(hasher.getContext());
for (const [key, value] of hasher.getContext()) {
contextAdditions.set(key, value);
}
return hasher.toString();
});
context = [...context, ...contextAdditions];
context = contextAdditions;
entries.sort();
return this._array(entries, false);
},
Expand Down