Skip to content

Commit

Permalink
init fast-benchmarks directory, includes #5792, #5842
Browse files Browse the repository at this point in the history
  • Loading branch information
Wendy authored and Wendy committed Apr 25, 2022
1 parent a4f739b commit b72e0df
Show file tree
Hide file tree
Showing 21 changed files with 19,013 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/web-components/fast-benchmarks/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
tsconfig.tsbuildinfo
node_modules
dist
yarn.lock
114 changes: 114 additions & 0 deletions packages/web-components/fast-benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# FAST Benchmarks

This is utility library for creating and running benchmark tests for FAST scenarios.

### Adding a Benchmark

To add a benchmark, create a new directory of the library name `/my-library/` and create a new subdirectory, eg `/my-library/my-benchmark`.
If the directory of the library you wish you add a benchmark already exists, such as `/fast-element/`, create a new subdirectory under, eg `/fast-element/my-benchmark/`.
Next, create an `index.html` file and `index.ts` file in `/my-benchmark`, these are required.

#### index.html

The html file references the index.js that is compiled from index.ts, which is compiled by running `yarn run build` (this step isn't necessary if you are running bnehcmark with `yarn run benchmark` with arguments)

```html
<!DOCTYPE html>
<script type="module" src="index.js"></script>
```

#### index.ts

```ts
```

#### Running a Benchmark

Benchmarks from this library are run with the `polymer/tachometer` package.
To run tachometer, you have to generate a tachometer config json file.
There are 2 ways to do this:

1. Follow the tachometer defined [schema](#https://raw.githubusercontent.com/Polymer/tachometer/master/config.schema.json) and generate a `tachometer.json` in `/fast-element/my-benchmark/`

tachometer.json

```json
{
"$schema": "https://raw.githubusercontent.com/Polymer/tachometer/master/config.schema.json",
"timeout": 0,
"benchmarks": [
{
"name": "my-benchmark",
"browser": {
"name": "chrome",
"headless": true,
"addArguments": ["--js-flags=--expose-gc", "--enable-precise-memory-info"]
},
"measurement": [
{
"name": "usedJSHeapSize",
"mode": "expression",
"expression": "window.usedJSHeapSize"
}
],

"expand": [
{
"name": "previous-version",
"url": "benchmarks/my-library/my-benchmark/index.html",
"packageVersions": {
"label": "1.4.0",
"dependencies": {
"my-library": "1.0.0"
}
}
},
{
"name": "local-version",
"url": "benchmarks/my-library/my-benchmark/index2.html",
"packageVersions": {
"label": "local",
"dependencies": {
"@microsoft/my-library": {
"kind": "git",
"repo": "https://github.com/microsoft/fast.git",
"ref": "my-local-branch",
"subdir": "packages/web-components/my-library",
"setupCommands": [
"yarn install",
"yarn --cwd ./packages/web-components/my-library build"
]
}
}
}
}
]
}
]
}
```

To run the benchmark, run the command `npx tach --config benchmarks/fast-element/my-benchmark/tachometer.json`

2. Pass in arguments accepted in \_\_, and fast-benchmarks will generate the tachometer config file based on the options you passed in.

To run the benchmark, supply all the options listed below, example: `yarn run benchmark --library=fast-element --test=binding -versions=1.8.0 1.9.0`.

### Options

| Option - | Example | Description |
| ------------------ | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--library` | `--library=fast-element` | The package library you want to run benchmarks in |
| `--benchmark` | `--benchmark=render` | Benchmark name |
| `--versions` | `--versions=1.9.0 1.4.0 local` | Supply versions of the library, [Available versions](#https://www.npmjs.com/package/@microsoft/fast-element), delimited by `space` |
| `--localBenchFile` | `--localBenchFile=index2.html` | This option is only turned on if you've supplied 'local' as one of the versions AND you want to add different implementation for the same benchmark test |

'local' version should be used when you added custom benchmark

if no 'local' version is provided in --versions, all listed versions will point to the index.html to run benchmarks

example:
`yarn run benchmark --library=fast-element --benchmark=binding --versions=1.9.0 local --localBenchFile=index2.html`
`yarn run benchmark --library=fast-element --benchmark=binding --versions=1.9.0 local`
`yarn run benchmark --library=fast-element --benchmark=binding --versions=1.9.0 master`
`yarn run benchmark --library=fast-foundation --benchmark=form-associated -v 2.34.0 2.42.1`
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<script type="module" src="index.js"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
attr,
css,
customElement,
FASTElement,
html,
observable,
repeat,
} from "@microsoft/fast-element";

import { _random, adjectives, colours, nouns } from "../../../utils/constants.js";
import runBenchmark from "./shared.js";

const itemCount = 250;
let id = 0;

export class RandomItem {
@observable label: string;

constructor(public readonly id: number) {
this.label =
adjectives[_random(adjectives.length)] +
" " +
colours[_random(colours.length)] +
" " +
nouns[_random(nouns.length)];
}
}

function generateData(count: number) {
const data = [];

for (let i = 0; i < count; i++) {
data.push(new RandomItem(++id));
}

return data;
}
const data: RandomItem[] = generateData(itemCount);

const xItemTemplate = html<XItem>`
<div @click="${x => x.onClick}" class="item">
${x => x.value}
</div>
`;

const styles = css`
.item {
display: flex;
}
`;
@customElement({
name: "x-item",
template: xItemTemplate,
styles,
})
class XItem extends FASTElement {
@attr value: string | undefined;

onClick(e: MouseEvent) {
console.log(e.type);
}
}

const xAppTemplate = html<XApp>`
<div id="container">
${repeat(
x => x.items,
html`
<x-item :value="${x => x.label}"></x-item>
`
)}
</div>
`;
@customElement({
name: "x-app",
template: xAppTemplate,
})
class XApp extends FASTElement {
@observable items: RandomItem[] = data;
}

runBenchmark();
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<script type="module" src="index2.js"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
attr,
bind,
css,
customElement,
FASTElement,
html,
oneTime,
repeat,
} from "@microsoft/fast-element";
import { _random, adjectives, colours, nouns } from "../../../utils/constants.js";
import runBenchmark from "./shared.js";

const itemCount = 250;
let id = 0;
export class RandomItem {
label: string;

constructor(public readonly id: number) {
this.label =
adjectives[_random(adjectives.length)] +
" " +
colours[_random(colours.length)] +
" " +
nouns[_random(nouns.length)];
}
}

function generateData(count: number) {
const data = [];

for (let i = 0; i < count; i++) {
data.push(new RandomItem(++id));
}

return data;
}
const data: RandomItem[] = generateData(itemCount);

const xItemTemplate = html<XItem>`
<div @click="${x => x.onClick}" class="item">
${x => x.value}
</div>
`;

const styles = css`
.item {
display: flex;
}
`;
@customElement({
name: "x-item",
template: xItemTemplate,
styles,
})
class XItem extends FASTElement {
@attr value: string | undefined;

onClick(e: MouseEvent) {
console.log(e.type);
}
}

const xAppTemplate = html<XApp>`
<div id="test-container">
${repeat(
x => x.items,
html<RandomItem>`
<x-item :value="${bind(x => x.label, oneTime)}"></x-item>
`
)}
</div>
`;
@customElement({
name: "x-app",
template: xAppTemplate,
})
class XApp extends FASTElement {
items: RandomItem[] = data;
}

runBenchmark();
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
declare global {
interface Window {
usedJSHeapSize: any;
gc: any;
}
interface Performance {
memory: any;
}
}

function measureMemory() {
if (window && performance && performance.memory) {
// Report results in MBs\
window.usedJSHeapSize = performance.memory.usedJSHeapSize / 1e6;
} else {
window.usedJSHeapSize = 0;
}
}

//support older browsesrs or if we're not using modules
export default async () => {
const container = document.createElement("div");
document.body.appendChild(container);

const create = () => {
const el = document.createElement("x-app");
return container.appendChild(el);
};
const destroy = () => {
container.innerHTML = "";
};
const getTestStartName = (name: string) => `${name}-start`;
const updateComplete = () => new Promise(r => requestAnimationFrame(r));

const render = async () => {
// can change to main dir file name
const test = "render";
const start = getTestStartName(test);
performance.mark(start);
create();
await updateComplete();
performance.measure(test, start);
destroy();
};
await render();
measureMemory();

// Log
performance
.getEntriesByType("measure")
.forEach(m => console.log(`${m.name}: ${m.duration.toFixed(3)}ms`));
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<script type="module" src="index.js"></script>
Loading

0 comments on commit b72e0df

Please sign in to comment.