mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
[compiler] add fixture for optimization across scopes
Adds a fixture based on internal case where our current output is quite a bit more verbose than the original memoization. See the comment in the fixture for more about the heuristic we can apply.
ghstack-source-id: e637a38140
Pull Request resolved: https://github.com/facebook/react/pull/29998
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component({ config }) {
|
||||
/**
|
||||
* The original memoization is optimal in the sense that it has
|
||||
* one output (the object) and one dependency (`config`). Both
|
||||
* the `a` and `b` functions will have to be recreated whenever
|
||||
* `config` changes, cascading to update the object.
|
||||
*
|
||||
* However, we currently only consider consecutive scopes for
|
||||
* merging, so we first see the `a` scope, then the `b` scope,
|
||||
* and see that the output of the `a` scope is used later -
|
||||
* so we don't merge these scopes, and so on.
|
||||
*
|
||||
* The more optimal thing would be to build a dependency graph
|
||||
* of scopes so that we can see the data flow is along the lines
|
||||
* of:
|
||||
*
|
||||
* config
|
||||
* / \
|
||||
* [a] [b]
|
||||
* \ /
|
||||
* [object]
|
||||
*
|
||||
* All the scopes (shown in []) are transitively dependent on
|
||||
* `config`, so they can be merged.
|
||||
*/
|
||||
const object = useMemo(() => {
|
||||
const a = (event) => {
|
||||
config?.onA?.(event);
|
||||
};
|
||||
|
||||
const b = (event) => {
|
||||
config?.onB?.(event);
|
||||
};
|
||||
|
||||
return {
|
||||
b,
|
||||
a,
|
||||
};
|
||||
}, [config]);
|
||||
|
||||
return <Stringify value={object} />;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component(t0) {
|
||||
const $ = _c(9);
|
||||
const { config } = t0;
|
||||
let t1;
|
||||
let t2;
|
||||
if ($[0] !== config) {
|
||||
t2 = (event) => {
|
||||
config?.onA?.(event);
|
||||
};
|
||||
$[0] = config;
|
||||
$[1] = t2;
|
||||
} else {
|
||||
t2 = $[1];
|
||||
}
|
||||
const a = t2;
|
||||
let t3;
|
||||
if ($[2] !== config) {
|
||||
t3 = (event_0) => {
|
||||
config?.onB?.(event_0);
|
||||
};
|
||||
$[2] = config;
|
||||
$[3] = t3;
|
||||
} else {
|
||||
t3 = $[3];
|
||||
}
|
||||
const b = t3;
|
||||
let t4;
|
||||
if ($[4] !== b || $[5] !== a) {
|
||||
t4 = { b, a };
|
||||
$[4] = b;
|
||||
$[5] = a;
|
||||
$[6] = t4;
|
||||
} else {
|
||||
t4 = $[6];
|
||||
}
|
||||
t1 = t4;
|
||||
const object = t1;
|
||||
let t5;
|
||||
if ($[7] !== object) {
|
||||
t5 = <Stringify value={object} />;
|
||||
$[7] = object;
|
||||
$[8] = t5;
|
||||
} else {
|
||||
t5 = $[8];
|
||||
}
|
||||
return t5;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: exception) Fixture not implemented
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Component({ config }) {
|
||||
/**
|
||||
* The original memoization is optimal in the sense that it has
|
||||
* one output (the object) and one dependency (`config`). Both
|
||||
* the `a` and `b` functions will have to be recreated whenever
|
||||
* `config` changes, cascading to update the object.
|
||||
*
|
||||
* However, we currently only consider consecutive scopes for
|
||||
* merging, so we first see the `a` scope, then the `b` scope,
|
||||
* and see that the output of the `a` scope is used later -
|
||||
* so we don't merge these scopes, and so on.
|
||||
*
|
||||
* The more optimal thing would be to build a dependency graph
|
||||
* of scopes so that we can see the data flow is along the lines
|
||||
* of:
|
||||
*
|
||||
* config
|
||||
* / \
|
||||
* [a] [b]
|
||||
* \ /
|
||||
* [object]
|
||||
*
|
||||
* All the scopes (shown in []) are transitively dependent on
|
||||
* `config`, so they can be merged.
|
||||
*/
|
||||
const object = useMemo(() => {
|
||||
const a = (event) => {
|
||||
config?.onA?.(event);
|
||||
};
|
||||
|
||||
const b = (event) => {
|
||||
config?.onB?.(event);
|
||||
};
|
||||
|
||||
return {
|
||||
b,
|
||||
a,
|
||||
};
|
||||
}, [config]);
|
||||
|
||||
return <Stringify value={object} />;
|
||||
}
|
||||
Reference in New Issue
Block a user