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

Implement caching in the JS version #138

Merged
merged 6 commits into from
Oct 4, 2015
Merged

Conversation

devongovett
Copy link
Contributor

This implements caching for the JS version, as suggested by @vjeux in #137. Here's the results of the same benchmark I used before, compared to the current master (after my previous optimizations):

new x 270 ops/sec ±122.16% (94 runs sampled)
old x 22.76 ops/sec ±4.21% (43 runs sampled)
new is the fastest
old is 92% slower


layoutNodeImpl(node, parentMaxWidth, parentDirection);

for (var key in node.layout)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: please always use { } even for one lines

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vjeux - this should probably be added to the static code analysis as part of the CI build. I'll look into it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, just checked and the eslint files only has one rule! That definitely needs fixing ;-)

@@ -1068,8 +1068,32 @@ var computeLayout = (function() {
child.nextAbsoluteChild = null;
}
}

function layoutNode(node, parentMaxWidth, parentDirection) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind porting the caching implementation to be closer to the C version this way it won't diverge in subtle ways

https://github.com/facebook/css-layout/blob/master/src/Layout.c#L1205-L1235

@vjeux
Copy link
Contributor

vjeux commented Oct 4, 2015

This is awesome :)

Would you mind sending a pull request with the benchmark as well, this way other people working on optimizations can have some kind of reference to play with

@@ -1068,8 +1068,32 @@ var computeLayout = (function() {
child.nextAbsoluteChild = null;
}
}

function layoutNode(node, parentMaxWidth, parentDirection) {
if (!node.lastLayout ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you support node.isDirty as well

@devongovett
Copy link
Contributor Author

Actually... the benchmark results above are not really valid since it used the same tree every run, so everything was cached (duh). Still way better though if you're just modifying a child rather than the whole tree. I'll update it.

@devongovett
Copy link
Contributor Author

Fixed nits and added node.isDirty, and node.shouldUpdate support. Also has to reset child layouts for any invalidated nodes before recomputing or the results will be wrong.

child.layout.height = undefined;
child.layout.top = 0;
child.layout.left = 0;
child.layout.bottom = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, what's going on with those two? We shouldn't compute those. They can be obtained from the other 4

@devongovett
Copy link
Contributor Author

Updated.

node.lastLayout.parentMaxWidth = parentMaxWidth;
node.lastLayout.direction = direction;

// Reset child layouts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't have to reset children layout, we're not doing that in the C version. Can you figure out what's going on here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, looks like we either need to update the C version or the Java one. Sucks that we have 2 different ways of reseting the children :x

I think that the C version is more "correct" as we're reseting the nodes that have been dirtied, not some random children.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it expected that all children of a node not have layout properties defined prior to processing that node? layoutNodeImpl seems to assume so. Without resetting, some isUndefined checks might fail where they shouldn't, and the position of a node is added to it's position from the previous layout pass. I think all children have to be reset. The C version just does this after a layout pass instead of before the next one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, it doesn't matter much indeed if we do it before the beginning or after the end. It's probably better to do it inside of the layout algorithm this way the callsite doesn't have to care and possibly introduce bugs.

vjeux added a commit that referenced this pull request Oct 4, 2015
Implement caching in the JS version
@vjeux vjeux merged commit 0faaabb into facebook:master Oct 4, 2015
@devongovett devongovett deleted the js-caching branch October 5, 2015 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants