-
Notifications
You must be signed in to change notification settings - Fork 24
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
Speed up nml import for nmls with many trees #4742
Conversation
return Object.values(trees).reduce( | ||
(maxId, tree) => (tree.treeId > maxId ? tree.treeId : maxId), | ||
Constants.MIN_TREE_ID - 1, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you also compare this to a simple for-loop? I think, I remember a case where this was another large performance boost. But maybe only because the aggregator was an object in that particular case. For a simple number it might be without benefit. Maybe worth to test, though.
Also: Did you compare line 76 to Math.max(tree.treeId, maxId)
? If your current way is faster, that's fine, but maybe there is no difference. In that case, I'd prefer the math.max version :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good remarks! I did some further testing and also noticed that I worked with a trees array (instead of an object) in my benchmarks 😕 . When using an object there doesn't seem to be a significant speedup over the existing lodash method using reduce or a foor lop (because Object.keys/values needs to be called). I did not spent much more time investigating because not calling getMaximumTreeId
20,000+ times provided the much greater speedup and optimizing the getMaximumTreeId
function seems more like premature optimization at this point :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using an object there doesn't seem to be a significant speedup over the existing lodash method using reduce or a foor lop (because Object.keys/values needs to be called).
Did you notice the "not significant speed ups" while micro benchmarking getMaximumTreeId
or while e2e-benchmarking the entire nml import? Since getMaximumTreeId
is also used in the rest of WK core, I'd find it worth it to swap the implementation to reduce/for-loop in case there's at least some speed-up factor :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I micro-benchmarked getMaximumTreeId
and smaller speedups are noticeable only when calling getMaximumTreeId
>10,000 times for a tracing with at least 20,000 trees. As we don't call it nearly that often (after my fix in this PR), I'm not convinced we need to optimize the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, totally agree then 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool that you spent the time to find this culprit :)
I noticed that the NML import for NMLs with many trees (20,000+) was very slow and had a look. Turns out I introduced this regression in #4541 by repeatedly calling the
getMaximumTreeId
function when importing trees.TheIgetMaximumTreeId
function was also rather slow as it created a potentially large array everytime it was called.replaced that with a simple reduce (10x speedup for tracings with >20,000 trees) and alsomade sure to only call thegetMaximumTreeId
function when it is necessary (~100x speedup during nml import).URL of deployed dev instance (used for testing):
Steps to test: