Skip to content

Commit f3ecff7

Browse files
refactor: use ElementIdGenerator for id generation in benchmarks (#21)
* refactor: use `ElementIdGenerator` for id generation in benchmarks * ci: update actions to use latest versions and add build with benchmarks test * fix: keep the `nextBunchId` function and pass it to `ElementIdGenerator` * chore: fix format * rerun benchmarks Looks like this made sending faster due to the internal counter state instead of calling maxCounter. Though I'm not sure why saving and loading is also faster - laptop variability? --------- Co-authored-by: Matthew Weidner <[email protected]>
1 parent abe6fb8 commit f3ecff7

File tree

4 files changed

+28
-43
lines changed

4 files changed

+28
-43
lines changed

.github/workflows/test.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14-
- uses: actions/checkout@v4
14+
- uses: actions/checkout@v6
1515

16-
- uses: actions/setup-node@v4
16+
- uses: actions/setup-node@v6
1717
with:
1818
node-version: "20"
1919
cache: "npm"
2020

2121
- run: npm ci
22-
2322
- run: npm test
23+
- run: npm run build
24+
- run: npm run benchmarks

benchmark_results.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,29 @@ Note: This is not a fair comparison to list/text CRDTs. The executions benchmark
1414
Send insertAfter and delete operations over a reliable link (e.g. WebSocket) - ElementId only.
1515
Updates and saved states use JSON encoding, with optional GZIP for saved states.
1616

17-
- Sender time (ms): 2229
17+
- Sender time (ms): 1440
1818
- Avg update size (bytes): 147.3
19-
- Receiver time (ms): 2214
20-
- Save time (ms): 14
19+
- Receiver time (ms): 1545
20+
- Save time (ms): 8
2121
- Save size (bytes): 1177551
22-
- Load time (ms): 28
23-
- Save time GZIP'd (ms): 83
24-
- Save size GZIP'd (bytes): 65897
25-
- Load time GZIP'd (ms): 53
22+
- Load time (ms): 14
23+
- Save time GZIP'd (ms): 43
24+
- Save size GZIP'd (bytes): 65895
25+
- Load time GZIP'd (ms): 27
2626
- Mem used estimate (MB): 2.7
2727

2828
## Insert-After, Custom Encoding
2929

3030
Send insertAfter and delete operations over a reliable link (e.g. WebSocket) - ElementId only.
3131
Updates use a custom string encoding; saved states use JSON with optional GZIP.
3232

33-
- Sender time (ms): 1943
33+
- Sender time (ms): 1201
3434
- Avg update size (bytes): 45.6
35-
- Receiver time (ms): 3237
36-
- Save time (ms): 13
35+
- Receiver time (ms): 2548
36+
- Save time (ms): 7
3737
- Save size (bytes): 1177551
38-
- Load time (ms): 19
39-
- Save time GZIP'd (ms): 57
40-
- Save size GZIP'd (bytes): 65889
41-
- Load time GZIP'd (ms): 49
38+
- Load time (ms): 15
39+
- Save time GZIP'd (ms): 41
40+
- Save size GZIP'd (bytes): 65895
41+
- Load time GZIP'd (ms): 26
4242
- Mem used estimate (MB): 2.7

benchmarks/insert_after_custom.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { assert } from "chai";
22
import { v4 as uuidv4 } from "uuid";
3-
import { ElementId, IdList, SavedIdList } from "../src";
3+
import { ElementId, ElementIdGenerator, IdList, SavedIdList } from "../src";
44
import {
55
avg,
66
getMemUsed,
@@ -10,7 +10,7 @@ import {
1010
sleep,
1111
} from "./internal/util";
1212

13-
const { edits, finalText } = realTextTraceEdits();
13+
const { edits } = realTextTraceEdits();
1414

1515
type Update = string;
1616

@@ -32,6 +32,8 @@ export async function insertAfterCustom() {
3232
return replicaId + replicaCounter++;
3333
}
3434

35+
const idGenerator = new ElementIdGenerator(nextBunchId);
36+
3537
// Perform the whole trace, sending all updates.
3638
const updates: string[] = [];
3739
let startTime = process.hrtime.bigint();
@@ -40,17 +42,7 @@ export async function insertAfterCustom() {
4042
let update: Update;
4143
if (edit[2] !== undefined) {
4244
const before = edit[0] === 0 ? null : sender.at(edit[0] - 1);
43-
let id: ElementId;
44-
// Try to extend before's bunch, so that it will be compressed.
45-
if (
46-
before !== null &&
47-
sender.maxCounter(before.bunchId) === before.counter
48-
) {
49-
id = { bunchId: before.bunchId, counter: before.counter + 1 };
50-
} else {
51-
// id = { bunchId: uuidv4(), counter: 0 };
52-
id = { bunchId: nextBunchId(), counter: 0 };
53-
}
45+
const id = idGenerator.generateAfter(before);
5446

5547
sender = sender.insertAfter(before, id);
5648

benchmarks/insert_after_json.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { assert } from "chai";
22
import { v4 as uuidv4 } from "uuid";
3-
import { ElementId, IdList, SavedIdList } from "../src";
3+
import { ElementId, ElementIdGenerator, IdList, SavedIdList } from "../src";
44
import {
55
avg,
66
getMemUsed,
@@ -10,7 +10,7 @@ import {
1010
sleep,
1111
} from "./internal/util";
1212

13-
const { edits, finalText } = realTextTraceEdits();
13+
const { edits } = realTextTraceEdits();
1414

1515
type Update =
1616
| {
@@ -38,6 +38,8 @@ export async function insertAfterJson() {
3838
return replicaId + replicaCounter++;
3939
}
4040

41+
const idGenerator = new ElementIdGenerator(nextBunchId);
42+
4143
// Perform the whole trace, sending all updates.
4244
const updates: string[] = [];
4345
let startTime = process.hrtime.bigint();
@@ -46,17 +48,7 @@ export async function insertAfterJson() {
4648
let updateObj: Update;
4749
if (edit[2] !== undefined) {
4850
const before = edit[0] === 0 ? null : sender.at(edit[0] - 1);
49-
let id: ElementId;
50-
// Try to extend before's bunch, so that it will be compressed.
51-
if (
52-
before !== null &&
53-
sender.maxCounter(before.bunchId) === before.counter
54-
) {
55-
id = { bunchId: before.bunchId, counter: before.counter + 1 };
56-
} else {
57-
// id = { bunchId: uuidv4(), counter: 0 };
58-
id = { bunchId: nextBunchId(), counter: 0 };
59-
}
51+
const id = idGenerator.generateAfter(before);
6052

6153
sender = sender.insertAfter(before, id);
6254

0 commit comments

Comments
 (0)