I was looking at https://github.com/facebook/react/issues/12700, and this seemed suspicious.

Consider this case:

```js
class App extends React.Component {
  componentDidMount() {
    for (let i = 0; i < 10000; i++) {
      ReactDOM.render(<div />, document.createElement('div'));
    }   
  }
  render() {
    return null
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
```

Profiling tells me we spend a *lot* of time searching for a root:

<img width="838" alt="screen shot 2018-08-07 at 12 12 52 am" src="https://user-images.githubusercontent.com/810438/43745499-f8716922-99d6-11e8-8822-380dcb15bfa3.png">

Adding some logging shows that e.g. for a 1000 roots, we'll run [this loop iteration](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberScheduler.js#L1798-L1846) 1000 times for the first root, then 999 times for the second root, then 998 times for the third root, etc. Oops.

This is surely a bug?
if (isRendering) {
    
    return currentSchedulerTime;
  }
   Check if there's pending work.
  findHighestPriorityRoot();
  if (
    nextFlushedExpirationTime === NoWork ||
    nextFlushedExpirationTime === Never
  ) {
    
    
    recomputeCurrentRendererTime();
    currentSchedulerTime = currentRendererTime;
    return currentSchedulerTime;
  }
   There's already pending work. We might be in the middle of a browser
   event. If we were to read the current time, it could cause multiple updates
   within the same event to receive different expiration times, leading to
   tearing. Return the last read time. During the next idle callback, the
   time will be updated.
  return currentSchedulerTime;
}
function requestWork(root: FiberRoot, expirationTime: ExpirationTime) {
  addRootToSchedule(root, expirationTime);
  if (isRendering) {