Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Commit 3e2d14f

Browse files
committed
updated fields benchmark
1 parent a4d440f commit 3e2d14f

File tree

12 files changed

+606
-418
lines changed

12 files changed

+606
-418
lines changed

benchmark/README.md

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,53 @@ but it is better than nothing.
2020
## 1000 Fields
2121

2222
```ts
23-
1. Agile nested State x 9,687 ops/sec ±2.46% (52 runs sampled)
24-
2. Hookstate x 5,170 ops/sec ±5.77% (31 runs sampled)
25-
3. Jotai x 4,578 ops/sec ±5.49% (57 runs sampled)
26-
4. Recoil x 3,790 ops/sec ±3.74% (55 runs sampled)
27-
5. Agile State x 1,480 ops/sec ±1.39% (12 runs sampled)
28-
6. Agile Collection x 498 ops/sec ±1.81% (61 runs sampled)
29-
7. Redux x 150 ops/sec ±1.72% (59 runs sampled)
30-
8. Mobx x 143 ops/sec ±0.92% (57 runs sampled)
31-
9. Valtio x 37.44 ops/sec ±5.17% (42 runs sampled)
23+
// 1 Field
24+
Agile Collection x 13,729 ops/sec ±3.42% (60 runs sampled) [updatedFieldsCount: 76468, renderFieldsCount: 73]
25+
Agile State x 19,008 ops/sec ±1.87% (66 runs sampled) [updatedFieldsCount: 103559, renderFieldsCount: 72]
26+
Agile nested State x 21,119 ops/sec ±1.45% (64 runs sampled) [updatedFieldsCount: 116226, renderFieldsCount: 72]
27+
Hookstate x 20,026 ops/sec ±0.68% (64 runs sampled) [updatedFieldsCount: 112513, renderFieldsCount: 112513]
28+
Jotai x 16,372 ops/sec ±3.34% (63 runs sampled) [updatedFieldsCount: 90275, renderFieldsCount: 90275]
29+
Mobx x 15,892 ops/sec ±3.42% (60 runs sampled) [updatedFieldsCount: 82400, renderFieldsCount: 82400]
30+
Nano Stores x 21,455 ops/sec ±1.00% (66 runs sampled) [updatedFieldsCount: 114136, renderFieldsCount: 114136]
31+
Recoil x 11,504 ops/sec ±3.44% (63 runs sampled) [updatedFieldsCount: 61553, renderFieldsCount: 61554]
32+
Redux x 13,070 ops/sec ±2.73% (62 runs sampled) [updatedFieldsCount: 69239, renderFieldsCount: 69240]
33+
Valtio x 9,962 ops/sec ±2.60% (60 runs sampled) [updatedFieldsCount: 54290, renderFieldsCount: 108579]
34+
35+
// 10 Fields
36+
Agile Collection x 10,651 ops/sec ±4.14% (58 runs sampled) [updatedFieldsCount: 56668, renderFieldsCount: 582]
37+
Agile State x 16,175 ops/sec ±1.55% (65 runs sampled) [updatedFieldsCount: 87481, renderFieldsCount: 80]
38+
Agile nested State x 20,703 ops/sec ±1.27% (65 runs sampled) [updatedFieldsCount: 113946, renderFieldsCount: 712]
39+
Hookstate x 18,733 ops/sec ±3.14% (59 runs sampled) [updatedFieldsCount: 105792, renderFieldsCount: 105801]
40+
Jotai x 15,602 ops/sec ±3.65% (61 runs sampled) [updatedFieldsCount: 85977, renderFieldsCount: 85986]
41+
Mobx x 9,283 ops/sec ±3.16% (52 runs sampled) [updatedFieldsCount: 50806, renderFieldsCount: 508060]
42+
Nano Stores x 20,125 ops/sec ±1.62% (62 runs sampled) [updatedFieldsCount: 108704, renderFieldsCount: 108713]
43+
Recoil x 11,103 ops/sec ±4.50% (61 runs sampled) [updatedFieldsCount: 62920, renderFieldsCount: 62939]
44+
Redux x 8,728 ops/sec ±1.61% (64 runs sampled) [updatedFieldsCount: 50794, renderFieldsCount: 507950]
45+
Valtio x 3,557 ops/sec ±2.96% (23 runs sampled) [updatedFieldsCount: 22473, renderFieldsCount: 449450]
46+
47+
// 100 Fields
48+
Agile Collection x 3,897 ops/sec ±3.01% (25 runs sampled) [updatedFieldsCount: 24427, renderFieldsCount: 2502]
49+
Agile State x 8,355 ops/sec ±0.85% (67 runs sampled) [updatedFieldsCount: 46249, renderFieldsCount: 173]
50+
Agile nested State x 18,641 ops/sec ±1.17% (63 runs sampled) [updatedFieldsCount: 98669, renderFieldsCount: 6802]
51+
Hookstate x 14,865 ops/sec ±2.51% (61 runs sampled) [updatedFieldsCount: 81616, renderFieldsCount: 81715]
52+
Jotai x 12,676 ops/sec ±3.09% (61 runs sampled) [updatedFieldsCount: 65930, renderFieldsCount: 66029]
53+
Mobx x 1,812 ops/sec ±1.49% (63 runs sampled) [updatedFieldsCount: 9639, renderFieldsCount: 963900]
54+
Nano Stores x 16,283 ops/sec ±1.39% (62 runs sampled) [updatedFieldsCount: 84772, renderFieldsCount: 84871]
55+
Recoil x 9,418 ops/sec ±2.94% (62 runs sampled) [updatedFieldsCount: 52425, renderFieldsCount: 52624]
56+
Redux x 1,896 ops/sec ±1.74% (62 runs sampled) [updatedFieldsCount: 10133, renderFieldsCount: 1013400]
57+
Valtio x 472 ops/sec ±2.97% (61 runs sampled) [updatedFieldsCount: 2494, renderFieldsCount: 498700]
58+
59+
// 1000 Fields
60+
Agile Collection x 503 ops/sec ±2.23% (62 runs sampled) [updatedFieldsCount: 2616, renderFieldsCount: 3520]
61+
Agile State x 1,437 ops/sec ±1.48% (59 runs sampled) [updatedFieldsCount: 7569, renderFieldsCount: 1061]
62+
Agile nested State x 9,411 ops/sec ±1.54% (56 runs sampled) [updatedFieldsCount: 46693, renderFieldsCount: 33243]
63+
Hookstate x 4,539 ops/sec ±3.61% (27 runs sampled) [updatedFieldsCount: 26381, renderFieldsCount: 27380]
64+
Jotai x 4,014 ops/sec ±5.35% (53 runs sampled) [updatedFieldsCount: 20390, renderFieldsCount: 21389]
65+
Mobx x 151 ops/sec ±0.75% (59 runs sampled) [updatedFieldsCount: 786, renderFieldsCount: 786000]
66+
Nano Stores x 5,511 ops/sec ±6.27% (32 runs sampled) [updatedFieldsCount: 31266, renderFieldsCount: 32265]
67+
Recoil x 3,562 ops/sec ±3.16% (58 runs sampled) [updatedFieldsCount: 18503, renderFieldsCount: 20502]
68+
Redux x 165 ops/sec ±1.40% (57 runs sampled) [updatedFieldsCount: 858, renderFieldsCount: 859000]
69+
Valtio x 38.76 ops/sec ±5.50% (42 runs sampled) [updatedFieldsCount: 215, renderFieldsCount: 429000]
3270
```
3371

3472
## Computed

benchmark/benchmarks/react/1000fields/bench/agilets/collection.tsx

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,65 @@ import ReactDom from 'react-dom';
33
import { Agile, Logger } from '@agile-ts/core';
44
import { useAgile, useValue } from '@agile-ts/react';
55

6-
const AgileApp = new Agile({ logConfig: { level: Logger.level.ERROR } });
7-
8-
const FIELDS = AgileApp.createCollection({
9-
initialData: Array.from(Array(1000).keys()).map((i) => ({
10-
id: i,
11-
name: `Field #${i + 1}`,
12-
})),
13-
});
14-
15-
function Field({ index }: { index: number | string }) {
16-
const ITEM = FIELDS.getItem(index);
17-
const item = useAgile(ITEM);
18-
19-
return (
20-
<div>
21-
Last {`<Field>`} render at: {new Date().toISOString()}
22-
&nbsp;
23-
<input
24-
value={item?.name}
25-
onChange={(e) => ITEM?.patch({ name: e.target.value })}
26-
/>
27-
</div>
28-
);
29-
}
6+
export default function (target: HTMLElement, fieldsCount: number) {
7+
const AgileApp = new Agile({ logConfig: { level: Logger.level.ERROR } });
8+
9+
const FIELDS = AgileApp.createCollection({
10+
initialData: Array.from(Array(fieldsCount).keys()).map((i) => ({
11+
id: i,
12+
name: `Field #${i + 1}`,
13+
})),
14+
});
15+
16+
let updatedFieldsCount = 0;
17+
let renderFieldsCount = 0;
3018

31-
function App() {
32-
const fieldKeys = useValue(FIELDS);
19+
function Field({ index }: { index: number | string }) {
20+
const ITEM = FIELDS.getItem(index);
21+
const item = useAgile(ITEM);
3322

34-
return (
35-
<div>
23+
renderFieldsCount++;
24+
25+
return (
3626
<div>
37-
Last {`<App>`} render at: {new Date().toISOString()}
27+
Last {`<Field>`} render at: {new Date().toISOString()}
28+
&nbsp;
29+
<input
30+
value={item?.name}
31+
onChange={(e) => {
32+
ITEM?.patch({ name: e.target.value });
33+
34+
updatedFieldsCount++;
35+
36+
(document.getElementById(
37+
'updatedFieldsCount'
38+
) as any).innerText = updatedFieldsCount;
39+
(document.getElementById(
40+
'renderFieldsCount'
41+
) as any).innerText = renderFieldsCount;
42+
}}
43+
/>
3844
</div>
39-
<br />
40-
{fieldKeys.map((key, i) => (
41-
<Field key={i} index={key} />
42-
))}
43-
</div>
44-
);
45-
}
45+
);
46+
}
47+
48+
function App() {
49+
const fieldKeys = useValue(FIELDS);
50+
51+
return (
52+
<div>
53+
<div>
54+
Last {`<App>`} render at: {new Date().toISOString()}
55+
</div>
56+
<br />
57+
{fieldKeys.map((key, i) => (
58+
<Field key={i} index={key} />
59+
))}
60+
<div id={'updatedFieldsCount'} />
61+
<div id={'renderFieldsCount'} />
62+
</div>
63+
);
64+
}
4665

47-
export default function (target: HTMLElement) {
4866
ReactDom.render(<App key={'agilets-collection'} />, target);
4967
}

benchmark/benchmarks/react/1000fields/bench/agilets/nestedState.tsx

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,62 @@ import * as ReactDom from 'react-dom';
33
import { Agile, Logger, State } from '@agile-ts/core';
44
import { useAgile } from '@agile-ts/react';
55

6-
const AgileApp = new Agile({ logConfig: { level: Logger.level.ERROR } });
7-
8-
const FIELDS = AgileApp.createState(
9-
Array.from(Array(1000).keys()).map((i) =>
10-
AgileApp.createState(`Field #${i + 1}`)
11-
)
12-
);
13-
14-
let updatedFieldsCount = 0;
15-
16-
function Field({ field }: { field: State<string> }) {
17-
const name = useAgile(field);
18-
19-
updatedFieldsCount++;
20-
21-
return (
22-
<div>
23-
Last {`<Field>`} render at: {new Date().toISOString()}
24-
&nbsp;
25-
<input
26-
value={name}
27-
onChange={(e) => {
28-
field.set(e.target.value);
29-
(document.getElementById(
30-
'updatedFieldsCount'
31-
) as any).innerText = updatedFieldsCount;
32-
}}
33-
/>
34-
</div>
6+
export default function (target: HTMLElement, fieldsCount: number) {
7+
const AgileApp = new Agile({ logConfig: { level: Logger.level.ERROR } });
8+
9+
const FIELDS = AgileApp.createState(
10+
Array.from(Array(fieldsCount).keys()).map((i) =>
11+
AgileApp.createState(`Field #${i + 1}`)
12+
)
3513
);
36-
}
3714

38-
function App() {
39-
const fields = useAgile(FIELDS);
40-
return (
41-
<div>
15+
let updatedFieldsCount = 0;
16+
let renderFieldsCount = 0;
17+
18+
function Field({ field }: { field: State<string> }) {
19+
const name = useAgile(field);
20+
21+
renderFieldsCount++;
22+
23+
return (
24+
<div>
25+
Last {`<Field>`} render at: {new Date().toISOString()}
26+
&nbsp;
27+
<input
28+
value={name}
29+
onChange={(e) => {
30+
field.set(e.target.value);
31+
32+
updatedFieldsCount++;
33+
34+
(document.getElementById(
35+
'updatedFieldsCount'
36+
) as any).innerText = updatedFieldsCount;
37+
(document.getElementById(
38+
'renderFieldsCount'
39+
) as any).innerText = renderFieldsCount;
40+
}}
41+
/>
42+
</div>
43+
);
44+
}
45+
46+
function App() {
47+
const fields = useAgile(FIELDS);
48+
return (
4249
<div>
43-
Last {`<App>`} render at: {new Date().toISOString()}
50+
<div>
51+
Last {`<App>`} render at: {new Date().toISOString()}
52+
</div>
53+
<br />
54+
{fields.map((field, index) => (
55+
<Field key={index} field={field} />
56+
))}
57+
<div id={'updatedFieldsCount'} />
58+
<div id={'renderFieldsCount'} />
4459
</div>
45-
<br />
46-
{fields.map((field, index) => (
47-
<Field key={index} field={field} />
48-
))}
49-
<div id={'updatedFieldsCount'} />
50-
</div>
51-
);
52-
}
60+
);
61+
}
5362

54-
export default function (target: HTMLElement) {
5563
ReactDom.render(<App key={'agilets-nested-state'} />, target);
5664
}

0 commit comments

Comments
 (0)