@samitouri / QOS-React-2 / commits / 9fb3a26174

Add logging for number of memo *blocks* (in addition to slots)

Useful for understanding and comparing how much memoization Forget applies vs how much developers previously memoized by hand.

Joe Savona committed Nov 30, 2023 at 15:20 UTC 9fb3a2617498d122a9c3dc7368155e7c25445903
3 files changed +26 -1
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Options.ts
+1
@@ -158,6 +158,7 @@ export type LoggerEvent =
158 fnLoc: t.SourceLocation | null;
159 fnName: string | null;
160 memoSlots: number;
161 + memoBlocks: number;
162 }
163 | {
164 kind: "PipelineError";
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts
+1
@@ -232,6 +232,7 @@ export function compileProgram(
232 fnLoc: fn.node.loc ?? null,
233 fnName: compiledFn.id?.name ?? null,
234 memoSlots: compiledFn.memoSlotsUsed,
235 + memoBlocks: compiledFn.memoBlocks,
236 });
237 } catch (err) {
238 hasCriticalError ||= isCriticalError(err);
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+24 -1
@@ -24,6 +24,7 @@ import {
24 ReactiveFunction,
25 ReactiveInstruction,
26 ReactiveScope,
27 + ReactiveScopeBlock,
28 ReactiveScopeDependency,
29 ReactiveTerminal,
30 ReactiveValue,
@@ -36,6 +37,7 @@ import { Err, Ok, Result } from "../Utils/Result";
37 import { assertExhaustive } from "../Utils/utils";
38 import { buildReactiveFunction } from "./BuildReactiveFunction";
39 import { SINGLE_CHILD_FBT_TAGS } from "./MemoizeFbtOperandsInSameScope";
40 +import { ReactiveFunctionVisitor, visitReactiveFunction } from "./visitors";
41
42 export type CodegenFunction = {
43 type: "CodegenFunction";
@@ -46,8 +48,16 @@ export type CodegenFunction = {
48 async: boolean;
49 loc: SourceLocation;
50
49 - // Compiler info for logging and heuristics
51 + /*
52 + * Compiler info for logging and heuristics
53 + * Number of memo slots (value passed to useMemoCache)
54 + */
55 memoSlotsUsed: number;
56 + /*
57 + * Number of memo *blocks* (reactive scopes) regardless of
58 + * how many inputs/outputs each block has
59 + */
60 + memoBlocks: number;
61 };
62
63 export function codegenReactiveFunction(
@@ -90,6 +100,9 @@ export function codegenReactiveFunction(
100 return Err(cx.errors);
101 }
102
103 + const countMemoBlockVisitor = new CountMemoBlockVisitor();
104 + visitReactiveFunction(fn, countMemoBlockVisitor, undefined);
105 +
106 return Ok({
107 type: "CodegenFunction",
108 loc: fn.loc,
@@ -99,9 +112,19 @@ export function codegenReactiveFunction(
112 generator: fn.generator,
113 async: fn.async,
114 memoSlotsUsed: cacheCount,
115 + memoBlocks: countMemoBlockVisitor.count,
116 });
117 }
118
119 +class CountMemoBlockVisitor extends ReactiveFunctionVisitor<void> {
120 + count: number = 0;
121 +
122 + override visitScope(scope: ReactiveScopeBlock, state: void): void {
123 + this.count += 1;
124 + this.traverseScope(scope, state);
125 + }
126 +}
127 +
128 function convertParameter(
129 param: Place | SpreadPattern
130 ): t.Identifier | t.RestElement {