Skip to content

Conversation

@jpap
Copy link

@jpap jpap commented Jan 17, 2019

See also: discussions in PR #852 and #786.

In addition to improving thread safety, it removes 8 bytes of heap per node.

@jpap
Copy link
Author

jpap commented Jan 17, 2019

Looks like the android Travis CI configuration is borked:

Buck wasn't able to parse /home/travis/build/facebook/yoga/lib/soloader/BUCK:
IOError: [Errno 2] No such file or directory: '/home/travis/build/facebook/yoga/tools/build_defs/fb_native_wrapper.bzl'
Call stack:
  File "/home/travis/buck/python-dsl/buck_parser/buck.py", line 1748, in process_with_diagnostics
    package_implicit_load=package_implicit_load,
  File "/home/travis/buck/python-dsl/buck_parser/buck.py", line 1638, in process
    package_implicit_load=package_implicit_load,
  File "/home/travis/buck/python-dsl/buck_parser/buck.py", line 1626, in _process_build_file
    package_implicit_load=package_implicit_load,
  File "/home/travis/buck/python-dsl/buck_parser/buck.py", line 1561, in _process
    exec(code, module.__dict__)
  File "/home/travis/build/facebook/yoga/lib/soloader/BUCK", line 6
    load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native")
  File "/home/travis/buck/python-dsl/buck_parser/buck.py", line 1292, in _load
    inner_env, module = self._process_include(build_include, is_implicit_include)
  File "/home/travis/buck/python-dsl/buck_parser/buck.py", line 1586, in _process_include
    package_implicit_load=None,
  File "/home/travis/buck/python-dsl/buck_parser/buck.py", line 1550, in _process
    with open(path, "r") as f:

This PR builds OK and tests pass on my local macOS machine.

See also: discussions in PR facebook#852 and facebook#786.

In addition to improving thread safety, it removes 8 bytes of heap per node.
@jpap jpap force-pushed the issue-769-thread-safety branch from 761b1d7 to 13ebc70 Compare January 17, 2019 02:56
@rmhartog
Copy link

There seems to be a file missing for CI indeed, I've proposed a fix in #843.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@davidaurelio has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@davidaurelio
Copy link
Contributor

This introduces double-digit regressions for layout calculation on ARM. I’m in favour of #852 at the moment, and will investigate whether we can remove the node counts.

@jpap
Copy link
Author

jpap commented Jan 30, 2019

This introduces double-digit regressions for layout calculation on ARM.

@davidaurelio do you have any figures to share, and is there any documentation on how to run the performance tests? There may be ways in which to recover the std::map overhead.

The other approach in #852 suffers from not being able to concurrently perform a layout of a given tree, and any number of cloned subtrees. This is because per-layout state is stored in each (shared) node, and the generation count is different for each layout run. (If this is not of practical concern, it could be documented as a limitation.)

@davidaurelio
Copy link
Contributor

@jpap for context: we have an internal device lab that will run benchmarks on physical Android and iOS devices. As much as I would like everyone to be able to run benchmarks, this will not become a publicly available resource.

Some numbers:

  • The synthetic benchmark that measures allocation, style assignment, layout calculation, layout reads, and deallocation recessed by ~11% (Android)
  • calculation in isolation recessed by ~11% on Android, ~8.5% on iOS
  • allocation/deallocation in isolation recessed by ~35% (Android)
  • The losses are smaller when using the Java API, as there’s fixed JNI overhead

These numbers don’t reflect real-life scenarios accurately (we will get there in the coming months), but they give an indication about the performance characteristics of changes.

The other approach in #852 suffers from not being able to concurrently perform a layout of a given tree, and any number of cloned subtrees. This is because per-layout state is stored in each (shared) node, and the generation count is different for each layout run. (If this is not of practical concern, it could be documented as a limitation.)

For now this is an acceptable limitation, and I agree that it should be documented. Shared subtrees are cloned lazily during layout calculation, and the only client making use of that is React Native. In their case, that’s thread safe, as the two highest ancestors sharing a node are never identical, and React Native treats subtrees as immutable.

That being said, it would be nicer to evolve Yoga into a direction where we can separate the layout outputs from the nodes, but this involves migrating client frameworks as well, including Litho, ComponentKit, React Native, React Native Windows, and internal projects at Facebook and other companies.

I think the short term goal should be to make parallel calculations on different trees possible.

Apologies if I am not always super responsive on Github. I really appreciate the input, though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants