This repository has been archived by the owner on Oct 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #169 from agile-ts/develop
New Release 🎉
- Loading branch information
Showing
149 changed files
with
4,981 additions
and
1,331 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--- | ||
'@agile-ts/api': patch | ||
'@agile-ts/core': patch | ||
'@agile-ts/event': patch | ||
'@agile-ts/logger': patch | ||
'@agile-ts/multieditor': patch | ||
'@agile-ts/proxytree': patch | ||
'@agile-ts/react': patch | ||
'@agile-ts/utils': patch | ||
'@agile-ts/vue': patch | ||
--- | ||
|
||
#### :rocket: New Feature | ||
* `react` | ||
* [#171](https://github.com/agile-ts/agile/pull/171) Add deps array to useAgile() hook ([@bennodev19](https://github.com/bennodev19)) | ||
* `core`, `event`, `react`, `vue` | ||
* [#166](https://github.com/agile-ts/agile/pull/166) Shared Agile Instance ([@bennodev19](https://github.com/bennodev19)) | ||
|
||
#### :nail_care: Polish | ||
* `api`, `core`, `event`, `logger`, `multieditor`, `react`, `utils` | ||
* [#168](https://github.com/agile-ts/agile/pull/168) Performance optimization ([@bennodev19](https://github.com/bennodev19)) | ||
* `core`, `event`, `react`, `vue` | ||
* [#166](https://github.com/agile-ts/agile/pull/166) Shared Agile Instance ([@bennodev19](https://github.com/bennodev19)) | ||
|
||
#### Committers: 1 | ||
- BennoDev ([@bennodev19](https://github.com/bennodev19)) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
MANUAL_BENCHMARK=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
# 🚀️ Benchmarks | ||
|
||
The `Benchmark Test Suites` are supposed to showcase where AgileTs is roughly located in terms of performance. | ||
I know a counter doesn't really show real world app performance, | ||
but it is better than nothing. | ||
|
||
### What do the results from benchmark js mean? | ||
https://stackoverflow.com/questions/28524653/what-do-the-results-from-benchmark-js-mean | ||
|
||
## Counter Benchmark | ||
|
||
```ts | ||
1. AgileTs.............43028 ops/se ±2.45 (63 runs sampled) | ||
2. PulseJs.............41086 ops/se ±2.60 (63 runs sampled) | ||
3. Nano Stores.........31933 ops/se ±1.27 (63 runs sampled) | ||
4. Zustand.............29329 ops/se ±1.30 (62 runs sampled) | ||
5. Redux...............28845 ops/se ±2.47 (61 runs sampled) | ||
6. Hookstate...........27555 ops/se ±5.00 (59 runs sampled) | ||
7. Mobx................27427 ops/se ±3.69 (62 runs sampled) | ||
8. Redux-Toolkit.......22191 ops/se ±1.06 (65 runs sampled) | ||
9. Jotai...............22157 ops/se ±4.10 (63 runs sampled) | ||
10. Valtio..............21089 ops/se ±0.77 (63 runs sampled) | ||
11. Recoil..............13926 ops/se ±2.12 (62 runs sampled) | ||
|
||
Fastest is AgileTs | ||
``` | ||
|
||
## 1000 Fields | ||
|
||
```ts | ||
// 1 Field | ||
1. Agile nested State..27992 ops/se ±1.73 (64 runs sampled) | ||
2. Pulse Collection....25547 ops/se ±1.04 (64 runs sampled) | ||
3. Agile State.........23962 ops/se ±2.16 (64 runs sampled) | ||
4. Nano Stores.........20662 ops/se ±1.76 (65 runs sampled) | ||
5. Hookstate...........19430 ops/se ±1.81 (61 runs sampled) | ||
6. Agile Collection....18491 ops/se ±2.13 (65 runs sampled) | ||
7. Jotai...............16029 ops/se ±3.39 (62 runs sampled) | ||
8. Mobx................15631 ops/se ±3.42 (61 runs sampled) | ||
9. Redux...............12698 ops/se ±2.86 (61 runs sampled) | ||
10. Recoil..............11183 ops/se ±3.73 (61 runs sampled) | ||
11. Valtio..............9728 ops/se ±2.81 (62 runs sampled) | ||
|
||
Fastest is Agile nested State | ||
|
||
// 10 Fields | ||
1. Agile nested State..27658 ops/se ±1.99 (64 runs sampled) | ||
2. Pulse Collection....24839 ops/se ±1.31 (65 runs sampled) | ||
3. Agile State.........19853 ops/se ±2.15 (64 runs sampled) | ||
4. Nano Stores.........19479 ops/se ±2.12 (60 runs sampled) | ||
5. Hookstate...........18104 ops/se ±3.37 (60 runs sampled) | ||
6. Jotai...............15472 ops/se ±2.45 (62 runs sampled) | ||
7. Agile Collection....13352 ops/se ±3.67 (61 runs sampled) | ||
8. Recoil..............10522 ops/se ±3.79 (58 runs sampled) | ||
9. Mobx................9477 ops/se ±1.94 (62 runs sampled) | ||
10. Redux...............8434 ops/se ±2.67 (47 runs sampled) | ||
11. Valtio..............3532 ops/se ±2.27 (23 runs sampled) | ||
|
||
Fastest is Agile nested State | ||
|
||
// 100 Fields | ||
1. Agile nested State..24124 ops/se ±1.05 (65 runs sampled) | ||
2. Pulse Collection....21912 ops/se ±1.35 (66 runs sampled) | ||
3. Nano Stores.........15638 ops/se ±1.63 (62 runs sampled) | ||
4. Hookstate...........13986 ops/se ±2.28 (59 runs sampled) | ||
5. Jotai...............12167 ops/se ±2.78 (63 runs sampled) | ||
6. Agile State.........9175 ops/se ±1.56 (51 runs sampled) | ||
7. Recoil..............8717 ops/se ±3.51 (49 runs sampled) | ||
8. Agile Collection....4177 ops/se ±1.64 (61 runs sampled) | ||
9. Redux...............1763 ops/se ±1.06 (63 runs sampled) | ||
10. Mobx................1699 ops/se ±1.82 (62 runs sampled) | ||
11. Valtio..............432 ops/se ±2.18 (60 runs sampled) | ||
|
||
Fastest is Agile nested State | ||
|
||
// 1000 Fields | ||
1. Agile nested State..10756 ops/se ±1.43 (58 runs sampled) | ||
2. Pulse Collection....9774 ops/se ±2.39 (58 runs sampled) | ||
3. Hookstate...........4737 ops/se ±4.33 (58 runs sampled) | ||
4. Nano Stores.........4638 ops/se ±6.40 (28 runs sampled) | ||
5. Jotai...............3352 ops/se ±4.17 (53 runs sampled) | ||
6. Recoil..............3139 ops/se ±4.69 (54 runs sampled) | ||
7. Agile State.........1389 ops/se ±1.52 (57 runs sampled) | ||
8. Agile Collection....500 ops/se ±1.89 (61 runs sampled) | ||
9. Redux...............154 ops/se ±1.48 (57 runs sampled) | ||
10. Mobx................144 ops/se ±1.06 (55 runs sampled) | ||
11. Valtio..............37 ops/se ±4.26 (40 runs sampled) | ||
|
||
Fastest is Agile nested State | ||
``` | ||
|
||
## Computed | ||
|
||
```ts | ||
1. Agile Hard Coded....32079 ops/se ±1.51 (62 runs sampled) | ||
2. Agile Auto Tracking.30974 ops/se ±2.21 (64 runs sampled) | ||
3. Nano Stores.........28821 ops/se ±1.49 (64 runs sampled) | ||
4. Jotai...............18922 ops/se ±2.12 (61 runs sampled) | ||
5. Recoil..............10103 ops/se ±2.47 (64 runs sampled) | ||
|
||
Fastest is Agile Hard Coded | ||
``` | ||
|
||
## 🏃 Running Benchmarks | ||
|
||
The Benchmark tests run on top of the [`benchmark.js` library](https://github.com/bestiejs/benchmark.js/) | ||
via [Playwright](https://github.com/microsoft/playwright) in the Chrome Browser. | ||
|
||
Before starting, make sure you are in the `/benchmark` directory. | ||
|
||
### 1️⃣ Install dependencies | ||
|
||
To prepare the dependencies, run: | ||
```ts | ||
yarn install | ||
``` | ||
|
||
### 2️⃣ Run Benchmark Test Suite | ||
|
||
Execute the benchmark located in `./benchmarks/react/counter`. | ||
```ts | ||
yarn run test:counter | ||
``` | ||
|
||
## ⭐️ Contribute | ||
|
||
Get a part of AgileTs and start contributing. We welcome any meaningful contribution. 😀 | ||
To find out more about contributing, check out the [CONTRIBUTING.md](https://github.com/agile-ts/agile/blob/master/CONTRIBUTING.md). | ||
|
||
<a href="https://codeclimate.com/github/agile-ts/agile/coverage.svg"> | ||
<img src="https://codeclimate.com/github/agile-ts/agile/badges/gpa.svg" alt="Maintainability"/> | ||
</a> | ||
|
||
## 🎉 Credits | ||
|
||
The Benchmark CLI is inspired by [`exome`](https://github.com/Marcisbee/exome). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
export interface CycleResultInterface { | ||
name: string; | ||
opsInSec: number; | ||
failRate: number; | ||
ranSampleCount: number; | ||
ui: any; | ||
} | ||
|
||
export function getCycleResult(event: any): CycleResultInterface { | ||
return { | ||
name: event.target.name, | ||
opsInSec: Math.round(event.target.hz), | ||
failRate: event.target.stats.rme.toFixed(2), | ||
ranSampleCount: event.target.stats.sample.length, | ||
ui: { | ||
count: event.target.output, | ||
}, | ||
}; | ||
} | ||
|
||
export function startBenchmarkLog(testSuiteName: string): void { | ||
console.log(`{white Starting Benchmark "{magenta.bold ${testSuiteName}}"..}`); | ||
} | ||
|
||
export function cycleLog( | ||
cycleResult: CycleResultInterface, | ||
...addition: any[] | ||
): void { | ||
console.log( | ||
`{gray ..Proceeded {green.bold ${cycleResult.name}} - {yellow ${cycleResult.opsInSec} ops/sec}}`, | ||
...addition | ||
); | ||
} | ||
|
||
export function endBenchmarkLog( | ||
testSuiteName: string, | ||
results: CycleResultInterface[], | ||
fastest: string[] | ||
): void { | ||
console.log(`{white ..End Benchmark "{magenta.bold ${testSuiteName}}"}\n\n`); | ||
|
||
results.sort((a, b) => { | ||
if (a.opsInSec < b.opsInSec) return 1; | ||
return -1; | ||
}); | ||
|
||
let resultString = ''; | ||
for (let i = 0; i < results.length; i++) { | ||
const cycleResult = results[i]; | ||
|
||
// Build Cycle Result Log | ||
const cycleString = `{bold.bgGreen ${ | ||
i + 1 | ||
}.} {bold.blue ${cycleResult.name | ||
.padEnd(20, '.') | ||
.replace(/(\.+)$/, '{red $1}')}}{yellow ${ | ||
cycleResult.opsInSec | ||
} ops/se} {gray ±${cycleResult.failRate}%} (${ | ||
cycleResult.ranSampleCount | ||
} runs sampled)`; | ||
|
||
resultString += `${cycleString}${i < results.length - 1 ? '\n' : ''}`; | ||
} | ||
|
||
// Build Leaderboard Header | ||
console.log('{bgYellow.white.bold Leaderboard:}\n'); | ||
|
||
// Print Leaderboard | ||
console.log(resultString); | ||
|
||
// Print fastest | ||
console.log(`\n{bold Fastest is {bold.green ${fastest}}}\n`); | ||
} |
67 changes: 67 additions & 0 deletions
67
benchmark/benchmarks/react/1000fields/bench/agilets/collection.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import React from 'react'; | ||
import ReactDom from 'react-dom'; | ||
import { createCollection, LogCodeManager } from '@agile-ts/core'; | ||
import { useAgile, useValue } from '@agile-ts/react'; | ||
|
||
LogCodeManager.getLogger().isActive = false; | ||
|
||
export default function (target: HTMLElement, fieldsCount: number) { | ||
const FIELDS = createCollection({ | ||
initialData: Array.from(Array(fieldsCount).keys()).map((i) => ({ | ||
id: i, | ||
name: `Field #${i + 1}`, | ||
})), | ||
}); | ||
|
||
let updatedFieldsCount = 0; | ||
let renderFieldsCount = 0; | ||
|
||
function Field({ index }: { index: number | string }) { | ||
const ITEM = FIELDS.getItem(index); | ||
const item = useAgile(ITEM); | ||
|
||
renderFieldsCount++; | ||
|
||
return ( | ||
<div> | ||
Last {`<Field>`} render at: {new Date().toISOString()} | ||
| ||
<input | ||
value={item?.name} | ||
onChange={(e) => { | ||
ITEM?.patch({ name: e.target.value }); | ||
|
||
updatedFieldsCount++; | ||
|
||
(document.getElementById( | ||
'updatedFieldsCount' | ||
) as any).innerText = updatedFieldsCount; | ||
(document.getElementById( | ||
'renderFieldsCount' | ||
) as any).innerText = renderFieldsCount; | ||
}} | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
function App() { | ||
const fieldKeys = useValue(FIELDS); | ||
|
||
return ( | ||
<div> | ||
<div> | ||
Last {`<App>`} render at: {new Date().toISOString()} | ||
</div> | ||
<br /> | ||
{fieldKeys.map((key, i) => ( | ||
<Field key={i} index={key} /> | ||
))} | ||
<div id={'updatedFieldsCount'} /> | ||
<div id={'renderFieldsCount'} /> | ||
</div> | ||
); | ||
} | ||
|
||
ReactDom.render(<App key={'agilets-collection'} />, target); | ||
} |
64 changes: 64 additions & 0 deletions
64
benchmark/benchmarks/react/1000fields/bench/agilets/nestedState.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import * as React from 'react'; | ||
import * as ReactDom from 'react-dom'; | ||
import { createState, LogCodeManager, State } from '@agile-ts/core'; | ||
import { useAgile } from '@agile-ts/react'; | ||
|
||
LogCodeManager.getLogger().isActive = false; | ||
|
||
export default function (target: HTMLElement, fieldsCount: number) { | ||
const FIELDS = createState( | ||
Array.from(Array(fieldsCount).keys()).map((i) => | ||
createState(`Field #${i + 1}`) | ||
) | ||
); | ||
|
||
let updatedFieldsCount = 0; | ||
let renderFieldsCount = 0; | ||
|
||
function Field({ field }: { field: State<string> }) { | ||
const name = useAgile(field); | ||
|
||
renderFieldsCount++; | ||
|
||
return ( | ||
<div> | ||
Last {`<Field>`} render at: {new Date().toISOString()} | ||
| ||
<input | ||
value={name} | ||
onChange={(e) => { | ||
field.set(e.target.value); | ||
|
||
updatedFieldsCount++; | ||
|
||
(document.getElementById( | ||
'updatedFieldsCount' | ||
) as any).innerText = updatedFieldsCount; | ||
(document.getElementById( | ||
'renderFieldsCount' | ||
) as any).innerText = renderFieldsCount; | ||
}} | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
function App() { | ||
const fields = useAgile(FIELDS); | ||
return ( | ||
<div> | ||
<div> | ||
Last {`<App>`} render at: {new Date().toISOString()} | ||
</div> | ||
<br /> | ||
{fields.map((field, index) => ( | ||
<Field key={index} field={field} /> | ||
))} | ||
<div id={'updatedFieldsCount'} /> | ||
<div id={'renderFieldsCount'} /> | ||
</div> | ||
); | ||
} | ||
|
||
ReactDom.render(<App key={'agilets-nested-state'} />, target); | ||
} |
Oops, something went wrong.