Skip to content

Commit

Permalink
Merge pull request #116 from serenity-kit/benchmarks
Browse files Browse the repository at this point in the history
benchmarks
  • Loading branch information
nikgraf authored Aug 21, 2024
2 parents 795ca83 + bf51fd5 commit e099e47
Show file tree
Hide file tree
Showing 18 changed files with 679 additions and 67 deletions.
11 changes: 11 additions & 0 deletions benchmarks/snapshots/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
## Install the Benchmarks

```sh
pnpm install
```

Note: The benchmarks use the secsync version published to npm. This is to avoid any performance hits that might exist in the development version.

## Run the Benchmarks

```sh
pnpm init:data
pnpm load:automerge
pnpm load:secsync:automerge
pnpm load:yjs2
pnpm load:secsync:yjs2
```

To reduce the amount of changes used for the benchmark uncomment this line in `initData.js`:
Expand Down
218 changes: 177 additions & 41 deletions benchmarks/snapshots/initData.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,50 @@ const fs = require("fs");
const zlib = require("zlib");
const automerge = require("@automerge/automerge");
const y = require("yjs");
const secsync = require("secsync");
const sodium = require("libsodium-wrappers");

async function main() {
await sodium.ready;

const docId = "6e46c006-5541-11ec-bf63-0242ac130002";
// generated using secsync.generateId(sodium);
const snapshotId = "DJ1VrlamnVQRkaqO5lpcZXFJCWC-gsZV";
const key = sodium.from_hex(
"724b092810ec86d7e35c9d067702b31ef90bc43a7b598626749914d6a3e033ed"
);
const clientAKeyPair = {
privateKey: sodium.from_base64(
"g3dtwb9XzhSzZGkxTfg11t1KEIb4D8rO7K54R6dnxArvgg_OzZ2GgREtG7F5LvNp3MS8p9vsio4r6Mq7SZDEgw"
),
publicKey: sodium.from_base64(
"74IPzs2dhoERLRuxeS7zadzEvKfb7IqOK-jKu0mQxIM"
),
keyType: "ed25519",
};

let { txns } = JSON.parse(
zlib.gunzipSync(fs.readFileSync("../automerge-paper.json.gz"))
);

let doc = automerge.from({ text: new automerge.Text() });
let docWithoutLastChanges = automerge.from({ text: new automerge.Text() });

const yDoc = new y.Doc();
const yDocChanges = [];
const yDocWithoutLastChanges = new y.Doc();
// const yDoc = new y.Doc();
// const yDocChanges = [];
// const yDocWithoutLastChanges = new y.Doc();

const y2Doc = new y.Doc();
const y2DocChanges = [];
const y2DocWithoutLastChanges = new y.Doc();

// NOTE: reduce the amount of changes used
// txns = txns.slice(0, 10000);
txns = txns.slice(0, 10000);

// yjs
yDoc.on("update", function (updateMessage) {
yDocChanges.push(updateMessage);
});
// // yjs
// yDoc.on("update", function (updateMessage) {
// yDocChanges.push(updateMessage);
// });

// yjs2
y2Doc.on("updateV2", function (updateMessage) {
Expand Down Expand Up @@ -54,24 +74,24 @@ async function main() {
);
}

// yjs
yDoc.transact((txn) => {
const text = txn.doc.getText();
for (const [pos, delHere, insContent] of patches) {
if (delHere > 0) text.delete(pos, delHere);
if (insContent !== "") text.insert(pos, insContent);
}
});
// // yjs
// yDoc.transact((txn) => {
// const text = txn.doc.getText();
// for (const [pos, delHere, insContent] of patches) {
// if (delHere > 0) text.delete(pos, delHere);
// if (insContent !== "") text.insert(pos, insContent);
// }
// });

if (i < txns.length - 1000) {
yDocWithoutLastChanges.transact((txn) => {
const text = txn.doc.getText();
for (const [pos, delHere, insContent] of patches) {
if (delHere > 0) text.delete(pos, delHere);
if (insContent !== "") text.insert(pos, insContent);
}
});
}
// if (i < txns.length - 1000) {
// yDocWithoutLastChanges.transact((txn) => {
// const text = txn.doc.getText();
// for (const [pos, delHere, insContent] of patches) {
// if (delHere > 0) text.delete(pos, delHere);
// if (insContent !== "") text.insert(pos, insContent);
// }
// });
// }

// yjs2
y2Doc.transact((txn) => {
Expand Down Expand Up @@ -116,38 +136,96 @@ async function main() {
})
);

console.log("Start writing Yjs files");
const allYChangesAsBase64 = yDocChanges.map((change) => {
return Buffer.from(change).toString("base64");
console.log("Start writing SecSync Automerge files");
const snapshotPublicData = {
snapshotId,
docId,
pubKey: sodium.to_base64(clientAKeyPair.publicKey),
parentSnapshotId: "",
parentSnapshotUpdateClocks: {},
};
const snapshot = secsync.createSnapshot(
automerge.save(doc),
snapshotPublicData,
key,
clientAKeyPair,
"",
"",
sodium
);
fs.writeFileSync("secsync.automerge.snapshot.json", JSON.stringify(snapshot));

const publicData = {
refSnapshotId: snapshotId,
docId,
pubKey: sodium.to_base64(clientAKeyPair.publicKey),
};
const allUpdates = automerge.getAllChanges(doc).map((change, index) => {
return secsync.createUpdate(
change,
publicData,
key,
clientAKeyPair,
index,
sodium
);
});

fs.writeFileSync(
"yjs.snapshot.json",
JSON.stringify({
doc: Buffer.from(y.encodeStateAsUpdate(yDoc)).toString("base64"),
})
"secsync.automerge.changes.json",
JSON.stringify({ updates: allUpdates })
);
fs.writeFileSync(
"yjs.changes.json",
JSON.stringify({ changes: allYChangesAsBase64 })

const snapshotWithoutLastChanges = secsync.createSnapshot(
automerge.save(docWithoutLastChanges),
snapshotPublicData,
key,
clientAKeyPair,
"",
"",
sodium
);

fs.writeFileSync(
"yjs.snapshot-with-changes.json",
"secsync.automerge.snapshot-with-changes.json",
JSON.stringify({
doc: Buffer.from(y.encodeStateAsUpdate(yDocWithoutLastChanges)).toString(
"base64"
),
changes: allYChangesAsBase64.slice(-1001),
snapshot: snapshotWithoutLastChanges,
updates: allUpdates.slice(-1001),
})
);

// console.log("Start writing Yjs files");
// const allYChangesAsBase64 = yDocChanges.map((change) => {
// return Buffer.from(change).toString("base64");
// });
// fs.writeFileSync(
// "yjs.snapshot.json",
// JSON.stringify({
// doc: Buffer.from(y.encodeStateAsUpdate(yDoc)).toString("base64"),
// })
// );
// fs.writeFileSync(
// "yjs.changes.json",
// JSON.stringify({ changes: allYChangesAsBase64 })
// );
// fs.writeFileSync(
// "yjs.snapshot-with-changes.json",
// JSON.stringify({
// doc: Buffer.from(y.encodeStateAsUpdate(yDocWithoutLastChanges)).toString(
// "base64"
// ),
// changes: allYChangesAsBase64.slice(-1001),
// })
// );

console.log("Start writing Yjs2 files");
const allY2ChangesAsBase64 = y2DocChanges.map((change) => {
return Buffer.from(change).toString("base64");
});
fs.writeFileSync(
"yjs2.snapshot.json",
JSON.stringify({
doc: Buffer.from(y.encodeStateAsUpdateV2(yDoc)).toString("base64"),
doc: Buffer.from(y.encodeStateAsUpdateV2(y2Doc)).toString("base64"),
})
);
fs.writeFileSync(
Expand All @@ -163,6 +241,64 @@ async function main() {
changes: allY2ChangesAsBase64.slice(-1001),
})
);

console.log("Start writing SecSync Yjs2 files");
const yjs2SnapshotPublicData = {
snapshotId,
docId,
pubKey: sodium.to_base64(clientAKeyPair.publicKey),
parentSnapshotId: "",
parentSnapshotUpdateClocks: {},
};
const yjs2Snapshot = secsync.createSnapshot(
y.encodeStateAsUpdateV2(y2Doc),
yjs2SnapshotPublicData,
key,
clientAKeyPair,
"",
"",
sodium
);
fs.writeFileSync("secsync.yjs2.snapshot.json", JSON.stringify(yjs2Snapshot));

const yjs2PublicData = {
refSnapshotId: snapshotId,
docId,
pubKey: sodium.to_base64(clientAKeyPair.publicKey),
};
const yjs2AllUpdates = y2DocChanges.map((change, index) => {
return secsync.createUpdate(
change,
yjs2PublicData,
key,
clientAKeyPair,
index,
sodium
);
});

fs.writeFileSync(
"secsync.yjs2.changes.json",
JSON.stringify({ updates: yjs2AllUpdates })
);

const yjs2SnapshotWithoutLastChanges = secsync.createSnapshot(
y.encodeStateAsUpdateV2(y2DocWithoutLastChanges),
yjs2SnapshotPublicData,
key,
clientAKeyPair,
"",
"",
sodium
);

fs.writeFileSync(
"secsync.yjs2.snapshot-with-changes.json",
JSON.stringify({
snapshot: yjs2SnapshotWithoutLastChanges,
updates: yjs2AllUpdates.slice(-1001),
})
);
}

main();
Loading

0 comments on commit e099e47

Please sign in to comment.