Add types to scripts and config files (#1277)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1277 Now that we have some TypeScript infra set up, move scripts (mainly the benchmarking one) and config files to TypeScript. Starts to move away a bit from the magic globals used in the JS environment. Reviewed By: yungsters Differential Revision: D45511176 fbshipit-source-id: 09bb1117a1b331758ed9d210e82d5b250577df81
This commit is contained in:
committed by
Facebook GitHub Bot
parent
19aed1d63e
commit
44ea3c1555
@@ -5,6 +5,9 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { getMeasureCounter } from "../tools/MeasureCounter";
|
||||
import { Yoga, YGBENCHMARK } from "../tools/globals";
|
||||
|
||||
const ITERATIONS = 2000;
|
||||
|
||||
YGBENCHMARK("Stack with flex", () => {
|
||||
@@ -12,7 +15,7 @@ YGBENCHMARK("Stack with flex", () => {
|
||||
root.setWidth(100);
|
||||
root.setHeight(100);
|
||||
|
||||
const measureCounter = getMeasureCounter(Yoga);
|
||||
const measureCounter = getMeasureCounter();
|
||||
|
||||
for (let i = 0; i < ITERATIONS; i++) {
|
||||
const child = Yoga.Node.create();
|
||||
@@ -21,14 +24,14 @@ YGBENCHMARK("Stack with flex", () => {
|
||||
root.insertChild(child, 0);
|
||||
}
|
||||
|
||||
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
|
||||
root.calculateLayout(undefined, undefined, Yoga.DIRECTION_LTR);
|
||||
root.freeRecursive();
|
||||
});
|
||||
|
||||
YGBENCHMARK("Align stretch in undefined axis", () => {
|
||||
const root = Yoga.Node.create();
|
||||
|
||||
const measureCounter = getMeasureCounter(Yoga);
|
||||
const measureCounter = getMeasureCounter();
|
||||
|
||||
for (let i = 0; i < ITERATIONS; i++) {
|
||||
const child = Yoga.Node.create();
|
||||
@@ -37,14 +40,14 @@ YGBENCHMARK("Align stretch in undefined axis", () => {
|
||||
root.insertChild(child, 0);
|
||||
}
|
||||
|
||||
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
|
||||
root.calculateLayout(undefined, undefined, Yoga.DIRECTION_LTR);
|
||||
root.freeRecursive();
|
||||
});
|
||||
|
||||
YGBENCHMARK("Nested flex", () => {
|
||||
const root = Yoga.Node.create();
|
||||
|
||||
const measureCounter = getMeasureCounter(Yoga);
|
||||
const measureCounter = getMeasureCounter();
|
||||
|
||||
const iterations = Math.pow(ITERATIONS, 1 / 2);
|
||||
|
||||
@@ -61,7 +64,7 @@ YGBENCHMARK("Nested flex", () => {
|
||||
}
|
||||
}
|
||||
|
||||
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
|
||||
root.calculateLayout(undefined, undefined, Yoga.DIRECTION_LTR);
|
||||
root.freeRecursive();
|
||||
});
|
||||
|
||||
@@ -104,6 +107,6 @@ YGBENCHMARK("Huge nested layout", () => {
|
||||
}
|
||||
}
|
||||
|
||||
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
|
||||
root.calculateLayout(undefined, undefined, Yoga.DIRECTION_LTR);
|
||||
root.freeRecursive();
|
||||
});
|
@@ -5,6 +5,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { getMeasureCounterMax } from "./tools/MeasureCounter";
|
||||
|
||||
test("measure_once_single_flexible_child", () => {
|
||||
const root = Yoga.Node.create();
|
||||
root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW);
|
||||
|
@@ -5,12 +5,14 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { getMeasureCounter } from "./tools/MeasureCounter";
|
||||
|
||||
test("dont_measure_single_grow_shrink_child", () => {
|
||||
const root = Yoga.Node.create();
|
||||
root.setWidth(100);
|
||||
root.setHeight(100);
|
||||
|
||||
const measureCounter = getMeasureCounter(Yoga, null, 100, 100);
|
||||
const measureCounter = getMeasureCounter(null, 100, 100);
|
||||
|
||||
const root_child0 = Yoga.Node.create();
|
||||
root_child0.setMeasureFunc(measureCounter.inc);
|
||||
@@ -25,9 +27,9 @@ test("dont_measure_single_grow_shrink_child", () => {
|
||||
});
|
||||
|
||||
test("dont_fail_with_incomplete_measure_dimensions", () => {
|
||||
const heightOnlyCallback = getMeasureCounter(Yoga, () => ({ height: 10 }));
|
||||
const widthOnlyCallback = getMeasureCounter(Yoga, () => ({ width: 10 }));
|
||||
const emptyCallback = getMeasureCounter(Yoga, () => ({}));
|
||||
const heightOnlyCallback = getMeasureCounter(() => ({ height: 10 }));
|
||||
const widthOnlyCallback = getMeasureCounter(() => ({ width: 10 }));
|
||||
const emptyCallback = getMeasureCounter(() => ({}));
|
||||
|
||||
const root = Yoga.Node.create();
|
||||
root.setWidth(100);
|
||||
|
67
javascript/tests/bin/run-bench.ts
Normal file
67
javascript/tests/bin/run-bench.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env ts-node
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import path from "path";
|
||||
|
||||
const WARMUP_ITERATIONS = 3;
|
||||
const BENCHMARK_ITERATIONS = 10;
|
||||
|
||||
const testFiles = process.argv.slice(2);
|
||||
|
||||
const testResults = new Map<string, Map<string, number>>();
|
||||
|
||||
for (const type of ["asmjs", "wasm"]) {
|
||||
globalThis.Yoga = require(type === "asmjs"
|
||||
? "../../dist/entrypoint/asmjs-sync"
|
||||
: "../../dist/entrypoint/wasm-sync");
|
||||
|
||||
for (const file of testFiles) {
|
||||
globalThis.YGBENCHMARK = (name: string, fn: () => void) => {
|
||||
let testEntry = testResults.get(name);
|
||||
|
||||
if (testEntry === undefined)
|
||||
testResults.set(name, (testEntry = new Map()));
|
||||
|
||||
for (let t = 0; t < WARMUP_ITERATIONS; ++t) fn();
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
for (let t = 0; t < BENCHMARK_ITERATIONS; ++t) fn();
|
||||
|
||||
const end = Date.now();
|
||||
|
||||
testEntry.set(type, (end - start) / BENCHMARK_ITERATIONS);
|
||||
};
|
||||
|
||||
const modulePath = path.resolve(file);
|
||||
|
||||
delete require.cache[require.resolve("../tools/globals")];
|
||||
delete require.cache[modulePath];
|
||||
require(modulePath);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Note: those tests are independants; there is no time relation to be expected between them`
|
||||
);
|
||||
|
||||
for (const [name, results] of testResults) {
|
||||
console.log();
|
||||
|
||||
const min = Math.min(Infinity, ...results.values());
|
||||
|
||||
console.log(name);
|
||||
|
||||
for (const [type, result] of results) {
|
||||
console.log(
|
||||
` - ${type}: ${result}ms (${Math.round((result / min) * 10000) / 100}%)`
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
require(`./tools`);
|
||||
|
||||
const fs = require(`fs`);
|
||||
const vm = require(`vm`);
|
||||
|
||||
const WARMUP_ITERATIONS = 3;
|
||||
const BENCHMARK_ITERATIONS = 10;
|
||||
|
||||
const testFiles = process.argv.slice(2).map((file) => {
|
||||
return fs.readFileSync(file).toString();
|
||||
});
|
||||
|
||||
const testResults = new Map();
|
||||
|
||||
for (const type of ["asmjs", "wasm"]) {
|
||||
for (const file of testFiles) {
|
||||
vm.runInNewContext(
|
||||
file,
|
||||
Object.assign(Object.create(global), {
|
||||
Yoga: require(type === "asmjs"
|
||||
? "../dist/entrypoint/asmjs-sync"
|
||||
: "../dist/entrypoint/wasm-sync"),
|
||||
YGBENCHMARK: function (name, fn) {
|
||||
let testEntry = testResults.get(name);
|
||||
|
||||
if (testEntry === undefined)
|
||||
testResults.set(name, (testEntry = new Map()));
|
||||
|
||||
for (let t = 0; t < WARMUP_ITERATIONS; ++t) fn();
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
for (let t = 0; t < BENCHMARK_ITERATIONS; ++t) fn();
|
||||
|
||||
const end = Date.now();
|
||||
|
||||
testEntry.set(type, (end - start) / BENCHMARK_ITERATIONS);
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Note: those tests are independants; there is no time relation to be expected between them`
|
||||
);
|
||||
|
||||
for (const [name, results] of testResults) {
|
||||
console.log();
|
||||
|
||||
const min = Math.min(Infinity, ...results.values());
|
||||
|
||||
console.log(name);
|
||||
|
||||
for (const [type, result] of results) {
|
||||
console.log(
|
||||
` - ${type}: ${result}ms (${Math.round((result / min) * 10000) / 100}%)`
|
||||
);
|
||||
}
|
||||
}
|
@@ -7,7 +7,19 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
global.getMeasureCounter = function (Yoga, cb, staticWidth, staticHeight) {
|
||||
import type { MeasureFunction } from "yoga-layout";
|
||||
import { Yoga } from "./globals";
|
||||
|
||||
export type MeasureCounter = {
|
||||
inc: MeasureFunction;
|
||||
get: () => number;
|
||||
};
|
||||
|
||||
export function getMeasureCounter(
|
||||
cb?: MeasureFunction | null,
|
||||
staticWidth = 0,
|
||||
staticHeight = 0
|
||||
): MeasureCounter {
|
||||
let counter = 0;
|
||||
|
||||
return {
|
||||
@@ -23,10 +35,10 @@ global.getMeasureCounter = function (Yoga, cb, staticWidth, staticHeight) {
|
||||
return counter;
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
global.getMeasureCounterMax = function (Yoga) {
|
||||
return getMeasureCounter(Yoga, (width, widthMode, height, heightMode) => {
|
||||
export function getMeasureCounterMax(): MeasureCounter {
|
||||
return getMeasureCounter((width, widthMode, height, heightMode) => {
|
||||
const measuredWidth =
|
||||
widthMode === Yoga.MEASURE_MODE_UNDEFINED ? 10 : width;
|
||||
const measuredHeight =
|
||||
@@ -34,10 +46,10 @@ global.getMeasureCounterMax = function (Yoga) {
|
||||
|
||||
return { width: measuredWidth, height: measuredHeight };
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
global.getMeasureCounterMin = function (Yoga) {
|
||||
return getMeasureCounter(Yoga, (width, widthMode, height, heightMode) => {
|
||||
export function getMeasureCounterMin(): MeasureCounter {
|
||||
return getMeasureCounter((width, widthMode, height, heightMode) => {
|
||||
const measuredWidth =
|
||||
widthMode === Yoga.MEASURE_MODE_UNDEFINED ||
|
||||
(widthMode == Yoga.MEASURE_MODE_AT_MOST && width > 10)
|
||||
@@ -51,4 +63,4 @@ global.getMeasureCounterMin = function (Yoga) {
|
||||
|
||||
return { width: measuredWidth, height: measuredHeight };
|
||||
});
|
||||
};
|
||||
}
|
27
javascript/tests/tools/globals.ts
Normal file
27
javascript/tests/tools/globals.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import type { Yoga } from "yoga-layout";
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var Yoga: Yoga | undefined;
|
||||
// eslint-disable-next-line no-var
|
||||
var YGBENCHMARK: (title: string, fn: () => void) => void;
|
||||
}
|
||||
|
||||
if (globalThis.Yoga === undefined) {
|
||||
throw new Error('Expected "Yoga" global to be set');
|
||||
}
|
||||
if (globalThis.YGBENCHMARK === undefined) {
|
||||
throw new Error('Expected "YGBENCHMARK" global to be set');
|
||||
}
|
||||
|
||||
const yoga = globalThis.Yoga;
|
||||
const benchmark = globalThis.YGBENCHMARK;
|
||||
|
||||
export { yoga as Yoga, benchmark as YGBENCHMARK };
|
Reference in New Issue
Block a user