瀏覽代碼

Merge pull request #15991 from overleaf/mj-doc-updater-benchmark

[document-updater] Add script for benchmarking apply function

GitOrigin-RevId: acb8174eec9d28870f05cca4802621f8f0c8a9bd
Mathias Jakobsen 2 年之前
父節點
當前提交
a6b272f9ce
共有 2 個文件被更改,包括 79 次插入0 次删除
  1. 78 0
      services/document-updater/benchmarks/apply.js
  2. 1 0
      services/document-updater/package.json

+ 78 - 0
services/document-updater/benchmarks/apply.js

@@ -0,0 +1,78 @@
+const text = require('../app/js/sharejs/types/text.js')
+
+const TEST_RUNS = 1_000_000
+const MAX_OPS_BATCH_SIZE = 35
+const KB = 1000
+
+function runTestCase(testCase, documentSizeBytes) {
+  const initialText = 'A'.repeat(documentSizeBytes)
+
+  console.log(`test: ${testCase.name}`)
+  console.log(`opsBatchSize\topsPerSeconds ${documentSizeBytes / 1000}KB`)
+  for (let i = 1; i <= MAX_OPS_BATCH_SIZE; i++) {
+    const ops = testCase(documentSizeBytes, i)
+
+    let timeTotal = 0
+    for (let i = 0; i < TEST_RUNS; i++) {
+      const start = performance.now()
+      try {
+        text.apply(initialText, ops)
+      } catch {
+        console.error(`test failed: ${testCase.name}, with ops:`)
+        console.error(ops)
+        return
+      }
+      const done = performance.now()
+      timeTotal += done - start
+    }
+
+    const opsPerSeconds = TEST_RUNS / (timeTotal / 1000)
+    console.log(`${i}\t${opsPerSeconds}`)
+  }
+}
+
+const randomAdditionTestCase = (docSize, opsSize) =>
+  Array.from({ length: opsSize }, () => ({
+    p: Math.floor(Math.random() * docSize),
+    i: 'B',
+  }))
+
+const sequentialAdditionsTestCase = (docSize, opsSize) =>
+  Array.from({ length: opsSize }, (_, i) => ({ p: i + docSize, i: 'B' }))
+
+const sequentialAdditionsInMiddleTestCase = (docSize, opsSize) =>
+  Array.from({ length: opsSize }, (_, i) => ({
+    p: Math.floor(docSize / 2) + i,
+    i: 'B',
+  }))
+
+const randomDeletionTestCase = (docSize, opsSize) =>
+  Array.from({ length: opsSize }, (_, i) => ({
+    p: Math.floor(Math.random() * (docSize - 1 - i)),
+    d: 'A',
+  }))
+
+const sequentialDeletionTestCase = (docSize, opsSize) =>
+  Array.from({ length: opsSize }, (_, i) => ({
+    p: docSize - 1 - i,
+    d: 'A',
+  }))
+
+const sequentialDeletionInMiddleTestCase = (docSize, opsSize) =>
+  Array.from({ length: opsSize }, (_, i) => ({
+    p: Math.floor(docSize / 2),
+    d: 'A',
+  }))
+
+for (const docSize of [10 * KB, 100 * KB]) {
+  for (const testCase of [
+    randomAdditionTestCase,
+    sequentialAdditionsTestCase,
+    sequentialAdditionsInMiddleTestCase,
+    randomDeletionTestCase,
+    sequentialDeletionTestCase,
+    sequentialDeletionInMiddleTestCase,
+  ]) {
+    runTestCase(testCase, docSize)
+  }
+}

+ 1 - 0
services/document-updater/package.json

@@ -9,6 +9,7 @@
     "test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP",
     "test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
     "test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
+    "benchmark:apply": "node benchmarks/apply",
     "nodemon": "node --watch $NODE_APP_OPTIONS app.js",
     "lint": "eslint --max-warnings 0 --format unix .",
     "format": "prettier --list-different $PWD/'**/*.js'",