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

Multithreading? #9

Open
joshaber opened this issue Dec 9, 2014 · 11 comments
Open

Multithreading? #9

joshaber opened this issue Dec 9, 2014 · 11 comments

Comments

@joshaber
Copy link
Owner

joshaber commented Dec 9, 2014

Should we allow component state to be changed from a background thread? Should it do realization, layout, or diffing on a background thread?

@joshaber
Copy link
Owner Author

joshaber commented Dec 9, 2014

I lean towards "no" for all of that, for simplicity's sake.

@nmn
Copy link

nmn commented Mar 13, 2015

From everything I know about React. If the codebase is written well enough, and Few seems to be, multi-threading should be fairly trivial to implement, for the diffing part.

Plus in Swift, there are GREAT tools for multithreading.

@joshaber
Copy link
Owner Author

I'm not sure anything involving multithreading is ever trivial 😄

I'm not convinced that the tradeoffs in complexity are worth it. I think we'd need some concrete cases where performance suffers to motivate this.

@nmn
Copy link

nmn commented Mar 14, 2015

@joshaber I just saw Few today, so I don't know how complicated it to implement. I have a lot of experience with React. With React, Pete Hunt was able to trivially move all the React code to a different thread. The only problem with that approach was that preventDefault couldn't be called on UI events.
From my understanding the same issue doesn't exist on iOS, as nothing has a default action to begin with.

Now perhaps, it is not important enough, and it is much more complicated to actually implement in Swift native code. But, I think that for larger apps, performance will become a bottleneck eventually, and multithreading could avoid that problem entirely.

Few is amazing, and very promising. I think it should reach for the maximum potential. Perhaps, its too early to work on a power feature like multithreading, but don't write it off for the future!

@jspahrsummers
Copy link
Collaborator

Note also that multithreading is not always a simple gain in performance. Sometimes the overhead involved in concurrency (and especially synchronization) can dominate the program, to where it's slower than if it were single-threaded.

@joshaber
Copy link
Owner Author

(Just for context, when I last talked to some of the folks working on Components one of the big motivations for multithreading was text layout with non-English languages.)

@adamjernst
Copy link
Collaborator

Threading is hard. The interesting thing is that React Native and ComponentKit have two totally different approaches to multithreading:

  • React Native has a single JS thread that is distinct from the app's main thread. However all JS operations must occur on this thread, so user interaction can be blocked waiting for JS to execute (e.g. state or model updates). The React Native guys are working on finessing this so that you can move certain expensive JS operations onto a separate thread.
  • ComponentKit uses totally immutable component instances. This means it's trivial for us to move component construction off the main thread and parallelize it, but we can't do scoped subtree updates—that would require that we be able to mutate the component tree after creation. Any state change anywhere in the tree requires a complete re-render, which is pretty expensive and limiting.

After we open source these two I would love to be part of the conversation about what Few should do for threading.

@nmn
Copy link

nmn commented Mar 23, 2015

@adamjernst Very interesting insights.

I have personal experience with React.js. In that case, all the JS operation do run on a single javascript thread, but as javascript is extremely async, the UI is never actually blocked. All the state and model updates in React are now async as well.

I don't know about componentKit. But you said Any state change anywhere in the tree requires a complete re-render, which is pretty expensive and limiting.
In the case of React.js and the DOM in the browser, it turned out that a complete re-render in pure code was still much faster than mutating views at all. Perhaps the same is true for iOS. Some benchmarking will show this soon.

I said that multithreading is a worthy goal earlier. This has all been informed by my experience of React.js

@mrjjwright
Copy link

@adamjernst If you had access to immutable data structures in ObjC++, with structural sharing, like those that exist in JS (not used in React currently either) and used those to represent your component tree, would you be able to update part of the component tree without a complete re-render?

@adamjernst
Copy link
Collaborator

@mrjjwright No. The two things that allow you to do scoped subtree updates:

  1. Component descriptors. Within render a component should be instantiating descriptors of what children it wants to have, not the actual child instances themselves. This allows the infra to step in and recycle existing children when possible.
  2. Refs. If a component needs access to an instance of a child, it must get it through the infrastructure, not via a reference that it stored previously. This is what React calls "refs".

@mrjjwright
Copy link

Yes React enforces those 2 rules well and from what I understood from Ari Grant’s talk so does Components. So I am still surprised that above you said that Components can’t currently handle scoped tree updates, but I am thinking it is because you can't mutate the component tree at all while with React they have a system appears immutable but is actually mutable via the internal ref system.

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

No branches or pull requests

5 participants