From f81e52a51e676a0e66be78ca4cef6dc9c80a8c1a Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Sun, 2 Apr 2017 15:45:48 -0700 Subject: [PATCH] change normalize logic to use mutable objects for performance --- src/transforms/normalize.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/transforms/normalize.js b/src/transforms/normalize.js index 11bf74c59..adaed0f5d 100644 --- a/src/transforms/normalize.js +++ b/src/transforms/normalize.js @@ -118,22 +118,28 @@ function normalizeNodeAndChildren(transform, node, schema) { // We can't just loop the children and normalize them, because in the process // of normalizing one child, we might end up creating another. Instead, we // have to normalize one at a time, and check for new children along the way. - let stack = node.nodes.map(n => n.key).toStack() - let set = new Set() + // PERF: use a mutable array here instead of an immutable stack. + const keys = node.nodes.toArray().map(n => n.key) // While there is still a child key that hasn't been normalized yet... - while (stack.size) { + while (keys.length) { const ops = transform.operations.length let key + // PERF: use a mutable set here since we'll be add to it a lot. + let set = new Set().asMutable() + // Unwind the stack, normalizing every child and adding it to the set. - while (key = stack.peek()) { + while (key = keys[0]) { const child = node.getChild(key) normalizeNodeAndChildren(transform, child, schema) - set = set.add(key) - stack = stack.pop() + set.add(key) + keys.shift() } + // Turn the set immutable to be able to compare against it. + set = set.asImmutable() + // PERF: Only re-find the node and re-normalize any new children if // operations occured that might have changed it. if (transform.operations.length != ops) { @@ -142,7 +148,7 @@ function normalizeNodeAndChildren(transform, node, schema) { // Add any new children back onto the stack. node.nodes.forEach((n) => { if (set.has(n.key)) return - stack = stack.push(n.key) + keys.unshift(n.key) }) } }