@fluidframework/merge-tree 2.92.0 → 2.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,27 +7,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const benchmark_1 = require("@fluid-tools/benchmark");
8
8
  const snapshot_utils_js_1 = require("./snapshot.utils.js");
9
9
  describe("MergeTree snapshots", () => {
10
- let summary;
11
10
  for (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {
12
- const test = (0, benchmark_1.benchmark)({
13
- type: benchmark_1.BenchmarkType.Measurement,
11
+ const test = (0, benchmark_1.benchmarkIt)({
14
12
  title: `load snapshot with ${summarySize} segments`,
15
13
  category: "snapshot loading",
16
- before: () => {
17
- const str = new snapshot_utils_js_1.TestString("id", {});
18
- for (let i = 0; i < summarySize; i++) {
19
- str.append("a", false);
20
- }
21
- str.applyPendingOps();
22
- summary = str.getSummary();
23
- },
24
- benchmarkFnAsync: async () => {
25
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
26
- await (0, snapshot_utils_js_1.loadSnapshot)(summary);
27
- },
28
- after: () => {
29
- summary = undefined;
30
- },
14
+ ...(0, benchmark_1.benchmarkDuration)({
15
+ benchmarkFnCustom: async (state) => {
16
+ const str = new snapshot_utils_js_1.TestString("id", {});
17
+ for (let i = 0; i < summarySize; i++) {
18
+ str.append("a", false);
19
+ }
20
+ str.applyPendingOps();
21
+ const summary = str.getSummary();
22
+ await state.timeAllBatchesAsync(async () => {
23
+ await (0, snapshot_utils_js_1.loadSnapshot)(summary);
24
+ });
25
+ },
26
+ }),
31
27
  });
32
28
  if (summarySize > 5000) {
33
29
  const currentTimeout = test.timeout();
@@ -1 +1 @@
1
- {"version":3,"file":"Snapshot.perf.spec.js","sourceRoot":"","sources":["../../src/test/Snapshot.perf.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,sDAAkE;AAGlE,2DAA+D;AAE/D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACpC,IAAI,OAAiC,CAAC;IAEtC,KAAK,MAAM,WAAW,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,IAAA,qBAAS,EAAC;YACtB,IAAI,EAAE,yBAAa,CAAC,WAAW;YAC/B,KAAK,EAAE,sBAAsB,WAAW,WAAW;YACnD,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,GAAG,EAAE;gBACZ,MAAM,GAAG,GAAG,IAAI,8BAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACxB,CAAC;gBAED,GAAG,CAAC,eAAe,EAAE,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAC5B,CAAC;YACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;gBAC5B,oEAAoE;gBACpE,MAAM,IAAA,gCAAY,EAAC,OAAQ,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,EAAE,GAAG,EAAE;gBACX,OAAO,GAAG,SAAS,CAAC;YACrB,CAAC;SACD,CAAC,CAAC;QAEH,IAAI,WAAW,GAAG,IAAI,EAAE,CAAC;YACxB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,iFAAiF;YACjF,IAAI,CAAC,OAAO,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree snapshots\", () => {\n\tlet summary: ISummaryTree | undefined;\n\n\tfor (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {\n\t\tconst test = benchmark({\n\t\t\ttype: BenchmarkType.Measurement,\n\t\t\ttitle: `load snapshot with ${summarySize} segments`,\n\t\t\tcategory: \"snapshot loading\",\n\t\t\tbefore: () => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < summarySize; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tsummary = str.getSummary();\n\t\t\t},\n\t\t\tbenchmarkFnAsync: async () => {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tawait loadSnapshot(summary!);\n\t\t\t},\n\t\t\tafter: () => {\n\t\t\t\tsummary = undefined;\n\t\t\t},\n\t\t});\n\n\t\tif (summarySize > 5000) {\n\t\t\tconst currentTimeout = test.timeout();\n\t\t\t// Default value of 2 seconds causes failure around P95 for large snapshot sizes.\n\t\t\ttest.timeout(currentTimeout === 0 ? 0 : Math.max(5000, currentTimeout));\n\t\t}\n\t}\n});\n"]}
1
+ {"version":3,"file":"Snapshot.perf.spec.js","sourceRoot":"","sources":["../../src/test/Snapshot.perf.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,sDAAwE;AAGxE,2DAA+D;AAE/D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACpC,KAAK,MAAM,WAAW,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,IAAA,uBAAW,EAAC;YACxB,KAAK,EAAE,sBAAsB,WAAW,WAAW;YACnD,QAAQ,EAAE,kBAAkB;YAC5B,GAAG,IAAA,6BAAiB,EAAC;gBACpB,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;oBAClC,MAAM,GAAG,GAAG,IAAI,8BAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;oBACxB,CAAC;oBACD,GAAG,CAAC,eAAe,EAAE,CAAC;oBACtB,MAAM,OAAO,GAAiB,GAAG,CAAC,UAAU,EAAE,CAAC;oBAC/C,MAAM,KAAK,CAAC,mBAAmB,CAAC,KAAK,IAAI,EAAE;wBAC1C,MAAM,IAAA,gCAAY,EAAC,OAAO,CAAC,CAAC;oBAC7B,CAAC,CAAC,CAAC;gBACJ,CAAC;aACD,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,WAAW,GAAG,IAAI,EAAE,CAAC;YACxB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,iFAAiF;YACjF,IAAI,CAAC,OAAO,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { benchmarkDuration, benchmarkIt } from \"@fluid-tools/benchmark\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree snapshots\", () => {\n\tfor (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {\n\t\tconst test = benchmarkIt({\n\t\t\ttitle: `load snapshot with ${summarySize} segments`,\n\t\t\tcategory: \"snapshot loading\",\n\t\t\t...benchmarkDuration({\n\t\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\t\tfor (let i = 0; i < summarySize; i++) {\n\t\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t\t}\n\t\t\t\t\tstr.applyPendingOps();\n\t\t\t\t\tconst summary: ISummaryTree = str.getSummary();\n\t\t\t\t\tawait state.timeAllBatchesAsync(async () => {\n\t\t\t\t\t\tawait loadSnapshot(summary);\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t}),\n\t\t});\n\n\t\tif (summarySize > 5000) {\n\t\t\tconst currentTimeout = test.timeout();\n\t\t\t// Default value of 2 seconds causes failure around P95 for large snapshot sizes.\n\t\t\ttest.timeout(currentTimeout === 0 ? 0 : Math.max(5000, currentTimeout));\n\t\t}\n\t}\n});\n"]}
@@ -23,73 +23,81 @@ function getCollectionSizes(ctor, baseSuiteType) {
23
23
  { name: "maximum keys", collection: maxSizeCollection, type: benchmark_1.BenchmarkType.Diagnostic },
24
24
  ];
25
25
  }
26
- function runAttributionCollectionSuite(ctor, suiteBaseType) {
26
+ function runAttributionCollectionSuite(ctor, suiteBaseType = benchmark_1.BenchmarkType.Measurement) {
27
27
  const collectionTestCases = getCollectionSizes(ctor, suiteBaseType);
28
28
  for (const { name, collection, type } of collectionTestCases) {
29
29
  describe(`using a collection with ${name}`, () => {
30
30
  const { length } = collection;
31
- (0, benchmark_1.benchmark)({
31
+ (0, benchmark_1.benchmarkIt)({
32
32
  title: "getAtOffset at the start",
33
- benchmarkFn: () => collection.getAtOffset(0),
33
+ ...(0, benchmark_1.benchmarkDuration)({ benchmarkFn: () => collection.getAtOffset(0) }),
34
34
  type,
35
35
  });
36
- (0, benchmark_1.benchmark)({
36
+ (0, benchmark_1.benchmarkIt)({
37
37
  title: "getAtOffset at the end",
38
- benchmarkFn: () => collection.getAtOffset(length - 1),
38
+ ...(0, benchmark_1.benchmarkDuration)({ benchmarkFn: () => collection.getAtOffset(length - 1) }),
39
39
  type,
40
40
  });
41
- (0, benchmark_1.benchmark)({
41
+ (0, benchmark_1.benchmarkIt)({
42
42
  title: "getAtOffset in the middle",
43
- benchmarkFn: () => collection.getAtOffset(length / 2),
43
+ ...(0, benchmark_1.benchmarkDuration)({ benchmarkFn: () => collection.getAtOffset(length / 2) }),
44
44
  type: benchmark_1.BenchmarkType.Diagnostic,
45
45
  });
46
- (0, benchmark_1.benchmark)({
46
+ (0, benchmark_1.benchmarkIt)({
47
47
  title: "getKeysInOffsetRange from start to end",
48
- benchmarkFn: () => collection.getKeysInOffsetRange(0),
48
+ ...(0, benchmark_1.benchmarkDuration)({ benchmarkFn: () => collection.getKeysInOffsetRange(0) }),
49
49
  type,
50
50
  });
51
- (0, benchmark_1.benchmark)({
51
+ (0, benchmark_1.benchmarkIt)({
52
52
  title: "getKeysInOffsetRange from start to mid",
53
- benchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),
53
+ ...(0, benchmark_1.benchmarkDuration)({
54
+ benchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),
55
+ }),
54
56
  type,
55
57
  });
56
- (0, benchmark_1.benchmark)({
58
+ (0, benchmark_1.benchmarkIt)({
57
59
  title: "getKeysInOffsetRange from mid to end",
58
- benchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),
60
+ ...(0, benchmark_1.benchmarkDuration)({
61
+ benchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),
62
+ }),
59
63
  type,
60
64
  });
61
- (0, benchmark_1.benchmark)({
65
+ (0, benchmark_1.benchmarkIt)({
62
66
  title: "getAll",
63
- benchmarkFn: () => collection.getAll(),
67
+ ...(0, benchmark_1.benchmarkDuration)({ benchmarkFn: () => collection.getAll() }),
64
68
  type,
65
69
  });
66
- (0, benchmark_1.benchmark)({
70
+ (0, benchmark_1.benchmarkIt)({
67
71
  title: "clone",
68
- benchmarkFn: () => collection.clone(),
72
+ ...(0, benchmark_1.benchmarkDuration)({ benchmarkFn: () => collection.clone() }),
69
73
  type,
70
74
  });
71
- (0, benchmark_1.benchmark)({
75
+ (0, benchmark_1.benchmarkIt)({
72
76
  title: "split + append in the middle",
73
- benchmarkFn: () => {
74
- const split = collection.splitAt(length / 2);
75
- collection.append(split);
76
- },
77
+ ...(0, benchmark_1.benchmarkDuration)({
78
+ benchmarkFn: () => {
79
+ const split = collection.splitAt(length / 2);
80
+ collection.append(split);
81
+ },
82
+ }),
77
83
  type,
78
84
  });
79
85
  });
80
86
  }
81
- (0, benchmark_1.benchmark)({
87
+ (0, benchmark_1.benchmarkIt)({
82
88
  title: "construction",
83
- benchmarkFn: () => new ctor(42, { type: "op", seq: 5 }),
89
+ ...(0, benchmark_1.benchmarkDuration)({ benchmarkFn: () => new ctor(42, { type: "op", seq: 5 }) }),
84
90
  type: suiteBaseType,
85
91
  });
86
92
  const segmentsToSerialize = collectionTestCases.map(({ collection }) => ({
87
93
  attribution: collection,
88
94
  cachedLength: collection.length,
89
95
  }));
90
- (0, benchmark_1.benchmark)({
96
+ (0, benchmark_1.benchmarkIt)({
91
97
  title: "serializing",
92
- benchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),
98
+ ...(0, benchmark_1.benchmarkDuration)({
99
+ benchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),
100
+ }),
93
101
  type: suiteBaseType,
94
102
  });
95
103
  const summary = ctor.serializeAttributionCollections(segmentsToSerialize);
@@ -99,11 +107,13 @@ function runAttributionCollectionSuite(ctor, suiteBaseType) {
99
107
  segments.push({
100
108
  cachedLength: summary.length - 9 * Math.floor(summary.length / 10),
101
109
  });
102
- (0, benchmark_1.benchmark)({
110
+ (0, benchmark_1.benchmarkIt)({
103
111
  title: "deserialize into 10 segments",
104
- benchmarkFn: () => {
105
- ctor.populateAttributionCollections(segments, summary);
106
- },
112
+ ...(0, benchmark_1.benchmarkDuration)({
113
+ benchmarkFn: () => {
114
+ ctor.populateAttributionCollections(segments, summary);
115
+ },
116
+ }),
107
117
  type: suiteBaseType,
108
118
  });
109
119
  }
@@ -111,7 +121,7 @@ describe("IAttributionCollection perf", () => {
111
121
  // There was a RedBlack tree based implementation for the collection entries, but the linear array based one won due to constant
112
122
  // factors/memory characteristics, so just kept the array based one.
113
123
  describe("list-based implementation", () => {
114
- runAttributionCollectionSuite(attributionCollection_js_1.AttributionCollection, benchmark_1.BenchmarkType.Measurement);
124
+ runAttributionCollectionSuite(attributionCollection_js_1.AttributionCollection);
115
125
  });
116
126
  });
117
127
  //# sourceMappingURL=attributionCollection.perf.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attributionCollection.perf.spec.js","sourceRoot":"","sources":["../../src/test/attributionCollection.perf.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\nimport type { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\n\nimport {\n\ttype IAttributionCollection,\n\tAttributionCollection as NewAttributionCollection,\n\ttype SerializedAttributionCollection,\n} from \"../attributionCollection.js\";\nimport type { ISegment } from \"../mergeTreeNodes.js\";\nimport { TextSegmentGranularity } from \"../textSegment.js\";\n\ninterface IAttributionCollectionCtor {\n\tnew (length: number, key?: AttributionKey): IAttributionCollection<AttributionKey>;\n\n\tserializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection;\n\n\tpopulateAttributionCollections(\n\t\tsegments: Iterable<Partial<ISegment>>,\n\t\tsummary: SerializedAttributionCollection,\n\t): void;\n}\n\nfunction getCollectionSizes(\n\tctor: IAttributionCollectionCtor,\n\tbaseSuiteType: BenchmarkType,\n): {\n\tname: string;\n\tcollection: IAttributionCollection<AttributionKey>;\n\ttype: BenchmarkType;\n}[] {\n\tconst singleKeyCollection = new ctor(5, { type: \"op\", seq: 42 });\n\tconst tenKeyCollection = new ctor(2, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < 10; i++) {\n\t\ttenKeyCollection.append(new ctor(3 * i, { type: \"op\", seq: i }));\n\t}\n\tconst maxSizeCollection = new ctor(1, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < TextSegmentGranularity; i++) {\n\t\tmaxSizeCollection.append(new ctor(1, { type: \"op\", seq: i }));\n\t}\n\treturn [\n\t\t{ name: \"one key\", collection: singleKeyCollection, type: BenchmarkType.Diagnostic },\n\t\t{ name: \"ten keys\", collection: tenKeyCollection, type: baseSuiteType },\n\t\t{ name: \"maximum keys\", collection: maxSizeCollection, type: BenchmarkType.Diagnostic },\n\t];\n}\n\nfunction runAttributionCollectionSuite(\n\tctor: IAttributionCollectionCtor,\n\tsuiteBaseType: BenchmarkType,\n): void {\n\tconst collectionTestCases = getCollectionSizes(ctor, suiteBaseType);\n\tfor (const { name, collection, type } of collectionTestCases) {\n\t\tdescribe(`using a collection with ${name}`, () => {\n\t\t\tconst { length } = collection;\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAtOffset at the start\",\n\t\t\t\tbenchmarkFn: () => collection.getAtOffset(0),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAtOffset at the end\",\n\t\t\t\tbenchmarkFn: () => collection.getAtOffset(length - 1),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAtOffset in the middle\",\n\t\t\t\tbenchmarkFn: () => collection.getAtOffset(length / 2),\n\t\t\t\ttype: BenchmarkType.Diagnostic,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to end\",\n\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(0),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to mid\",\n\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getKeysInOffsetRange from mid to end\",\n\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"getAll\",\n\t\t\t\tbenchmarkFn: () => collection.getAll(),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"clone\",\n\t\t\t\tbenchmarkFn: () => collection.clone(),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmark({\n\t\t\t\ttitle: \"split + append in the middle\",\n\t\t\t\tbenchmarkFn: () => {\n\t\t\t\t\tconst split = collection.splitAt(length / 2);\n\t\t\t\t\tcollection.append(split);\n\t\t\t\t},\n\t\t\t\ttype,\n\t\t\t});\n\t\t});\n\t}\n\n\tbenchmark({\n\t\ttitle: \"construction\",\n\t\tbenchmarkFn: () => new ctor(42, { type: \"op\", seq: 5 }),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst segmentsToSerialize = collectionTestCases.map(({ collection }) => ({\n\t\tattribution: collection,\n\t\tcachedLength: collection.length,\n\t}));\n\n\tbenchmark({\n\t\ttitle: \"serializing\",\n\t\tbenchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst summary = ctor.serializeAttributionCollections(segmentsToSerialize);\n\tconst segments: Partial<ISegment>[] = Array.from({ length: 9 }, () => ({\n\t\tcachedLength: Math.floor(summary.length / 10),\n\t})) as ISegment[];\n\tsegments.push({\n\t\tcachedLength: summary.length - 9 * Math.floor(summary.length / 10),\n\t} satisfies Partial<ISegment>);\n\tbenchmark({\n\t\ttitle: \"deserialize into 10 segments\",\n\t\tbenchmarkFn: () => {\n\t\t\tctor.populateAttributionCollections(segments, summary);\n\t\t},\n\t\ttype: suiteBaseType,\n\t});\n}\n\ndescribe(\"IAttributionCollection perf\", () => {\n\t// There was a RedBlack tree based implementation for the collection entries, but the linear array based one won due to constant\n\t// factors/memory characteristics, so just kept the array based one.\n\tdescribe(\"list-based implementation\", () => {\n\t\trunAttributionCollectionSuite(NewAttributionCollection, BenchmarkType.Measurement);\n\t});\n});\n"]}
1
+ {"version":3,"file":"attributionCollection.perf.spec.js","sourceRoot":"","sources":["../../src/test/attributionCollection.perf.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmarkDuration, benchmarkIt } from \"@fluid-tools/benchmark\";\nimport type { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\n\nimport {\n\ttype IAttributionCollection,\n\tAttributionCollection as NewAttributionCollection,\n\ttype SerializedAttributionCollection,\n} from \"../attributionCollection.js\";\nimport type { ISegment } from \"../mergeTreeNodes.js\";\nimport { TextSegmentGranularity } from \"../textSegment.js\";\n\ninterface IAttributionCollectionCtor {\n\tnew (length: number, key?: AttributionKey): IAttributionCollection<AttributionKey>;\n\n\tserializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection;\n\n\tpopulateAttributionCollections(\n\t\tsegments: Iterable<Partial<ISegment>>,\n\t\tsummary: SerializedAttributionCollection,\n\t): void;\n}\n\nfunction getCollectionSizes(\n\tctor: IAttributionCollectionCtor,\n\tbaseSuiteType: BenchmarkType,\n): {\n\tname: string;\n\tcollection: IAttributionCollection<AttributionKey>;\n\ttype: BenchmarkType;\n}[] {\n\tconst singleKeyCollection = new ctor(5, { type: \"op\", seq: 42 });\n\tconst tenKeyCollection = new ctor(2, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < 10; i++) {\n\t\ttenKeyCollection.append(new ctor(3 * i, { type: \"op\", seq: i }));\n\t}\n\tconst maxSizeCollection = new ctor(1, { type: \"op\", seq: 0 });\n\tfor (let i = 1; i < TextSegmentGranularity; i++) {\n\t\tmaxSizeCollection.append(new ctor(1, { type: \"op\", seq: i }));\n\t}\n\treturn [\n\t\t{ name: \"one key\", collection: singleKeyCollection, type: BenchmarkType.Diagnostic },\n\t\t{ name: \"ten keys\", collection: tenKeyCollection, type: baseSuiteType },\n\t\t{ name: \"maximum keys\", collection: maxSizeCollection, type: BenchmarkType.Diagnostic },\n\t];\n}\n\nfunction runAttributionCollectionSuite(\n\tctor: IAttributionCollectionCtor,\n\tsuiteBaseType: BenchmarkType = BenchmarkType.Measurement,\n): void {\n\tconst collectionTestCases = getCollectionSizes(ctor, suiteBaseType);\n\tfor (const { name, collection, type } of collectionTestCases) {\n\t\tdescribe(`using a collection with ${name}`, () => {\n\t\t\tconst { length } = collection;\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAtOffset at the start\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(0) }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAtOffset at the end\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(length - 1) }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAtOffset in the middle\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAtOffset(length / 2) }),\n\t\t\t\ttype: BenchmarkType.Diagnostic,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to end\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getKeysInOffsetRange(0) }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getKeysInOffsetRange from start to mid\",\n\t\t\t\t...benchmarkDuration({\n\t\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(0, length / 2),\n\t\t\t\t}),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getKeysInOffsetRange from mid to end\",\n\t\t\t\t...benchmarkDuration({\n\t\t\t\t\tbenchmarkFn: () => collection.getKeysInOffsetRange(length / 2, length - 1),\n\t\t\t\t}),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"getAll\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.getAll() }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"clone\",\n\t\t\t\t...benchmarkDuration({ benchmarkFn: () => collection.clone() }),\n\t\t\t\ttype,\n\t\t\t});\n\n\t\t\tbenchmarkIt({\n\t\t\t\ttitle: \"split + append in the middle\",\n\t\t\t\t...benchmarkDuration({\n\t\t\t\t\tbenchmarkFn: () => {\n\t\t\t\t\t\tconst split = collection.splitAt(length / 2);\n\t\t\t\t\t\tcollection.append(split);\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\ttype,\n\t\t\t});\n\t\t});\n\t}\n\n\tbenchmarkIt({\n\t\ttitle: \"construction\",\n\t\t...benchmarkDuration({ benchmarkFn: () => new ctor(42, { type: \"op\", seq: 5 }) }),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst segmentsToSerialize = collectionTestCases.map(({ collection }) => ({\n\t\tattribution: collection,\n\t\tcachedLength: collection.length,\n\t}));\n\n\tbenchmarkIt({\n\t\ttitle: \"serializing\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFn: () => ctor.serializeAttributionCollections(segmentsToSerialize),\n\t\t}),\n\t\ttype: suiteBaseType,\n\t});\n\n\tconst summary = ctor.serializeAttributionCollections(segmentsToSerialize);\n\tconst segments: Partial<ISegment>[] = Array.from({ length: 9 }, () => ({\n\t\tcachedLength: Math.floor(summary.length / 10),\n\t})) as ISegment[];\n\tsegments.push({\n\t\tcachedLength: summary.length - 9 * Math.floor(summary.length / 10),\n\t} satisfies Partial<ISegment>);\n\tbenchmarkIt({\n\t\ttitle: \"deserialize into 10 segments\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFn: () => {\n\t\t\t\tctor.populateAttributionCollections(segments, summary);\n\t\t\t},\n\t\t}),\n\t\ttype: suiteBaseType,\n\t});\n}\n\ndescribe(\"IAttributionCollection perf\", () => {\n\t// There was a RedBlack tree based implementation for the collection entries, but the linear array based one won due to constant\n\t// factors/memory characteristics, so just kept the array based one.\n\tdescribe(\"list-based implementation\", () => {\n\t\trunAttributionCollectionSuite(NewAttributionCollection);\n\t});\n});\n"]}
package/eslint.config.mts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import type { Linter } from "eslint";
7
- import { recommended } from "../../../common/build/eslint-config-fluid/flat.mts";
7
+ import { recommended } from "@fluidframework/eslint-config-fluid/flat.mts";
8
8
 
9
9
  const config: Linter.Config[] = [
10
10
  ...recommended,
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { BenchmarkType, benchmark } from "@fluid-tools/benchmark";
5
+ import { benchmarkDuration, benchmarkIt } from "@fluid-tools/benchmark";
6
6
  import { MergeTree } from "../mergeTree.js";
7
7
  import { MergeTreeDeltaType } from "../ops.js";
8
8
  import { TextSegment } from "../textSegment.js";
@@ -15,52 +15,65 @@ function constructTree(numOfSegments) {
15
15
  }
16
16
  const TREE_SIZE = 7500;
17
17
  describe("MergeTree insertion", () => {
18
- benchmark({
19
- type: BenchmarkType.Measurement,
18
+ benchmarkIt({
20
19
  title: "insert into empty tree",
21
- benchmarkFn: () => {
22
- const emptyTree = new MergeTree();
23
- emptyTree.insertSegments(0, [TextSegment.make("a")], emptyTree.localPerspective, { seq: 0, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
24
- },
20
+ ...benchmarkDuration({
21
+ benchmarkFn: () => {
22
+ const emptyTree = new MergeTree();
23
+ emptyTree.insertSegments(0, [TextSegment.make("a")], emptyTree.localPerspective, { seq: 0, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
24
+ },
25
+ }),
25
26
  });
26
- let startTree = constructTree(TREE_SIZE);
27
- benchmark({
28
- type: BenchmarkType.Measurement,
27
+ benchmarkIt({
29
28
  title: "insert at start of large tree",
30
- benchmarkFn: () => {
31
- for (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {
32
- startTree.insertSegments(0, [TextSegment.make("a")], startTree.localPerspective, { seq: i + 1, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
33
- }
34
- },
35
- beforeEachBatch: () => {
36
- startTree = constructTree(TREE_SIZE);
37
- },
29
+ ...benchmarkDuration({
30
+ benchmarkFnCustom: async (state) => {
31
+ let startTree = constructTree(TREE_SIZE);
32
+ let keepRunning;
33
+ do {
34
+ startTree = constructTree(TREE_SIZE);
35
+ keepRunning = state.timeBatch(() => {
36
+ for (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {
37
+ startTree.insertSegments(0, [TextSegment.make("a")], startTree.localPerspective, { seq: i + 1, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
38
+ }
39
+ });
40
+ } while (keepRunning);
41
+ },
42
+ }),
38
43
  });
39
- let middleTree = constructTree(TREE_SIZE);
40
- benchmark({
41
- type: BenchmarkType.Measurement,
44
+ benchmarkIt({
42
45
  title: "insert at middle of large tree",
43
- benchmarkFn: () => {
44
- for (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {
45
- middleTree.insertSegments(TREE_SIZE / 2, [TextSegment.make("a")], middleTree.localPerspective, { seq: i + 1, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
46
- }
47
- },
48
- beforeEachBatch: () => {
49
- middleTree = constructTree(TREE_SIZE);
50
- },
46
+ ...benchmarkDuration({
47
+ benchmarkFnCustom: async (state) => {
48
+ let middleTree = constructTree(TREE_SIZE);
49
+ let keepRunning;
50
+ do {
51
+ middleTree = constructTree(TREE_SIZE);
52
+ keepRunning = state.timeBatch(() => {
53
+ for (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {
54
+ middleTree.insertSegments(TREE_SIZE / 2, [TextSegment.make("a")], middleTree.localPerspective, { seq: i + 1, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
55
+ }
56
+ });
57
+ } while (keepRunning);
58
+ },
59
+ }),
51
60
  });
52
- let endTree = constructTree(TREE_SIZE);
53
- benchmark({
54
- type: BenchmarkType.Measurement,
61
+ benchmarkIt({
55
62
  title: "insert at end of large tree",
56
- benchmarkFn: () => {
57
- for (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {
58
- endTree.insertSegments(i, [TextSegment.make("a")], endTree.localPerspective, { seq: i + 1, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
59
- }
60
- },
61
- beforeEachBatch: () => {
62
- endTree = constructTree(TREE_SIZE);
63
- },
63
+ ...benchmarkDuration({
64
+ benchmarkFnCustom: async (state) => {
65
+ let endTree = constructTree(TREE_SIZE);
66
+ let keepRunning;
67
+ do {
68
+ endTree = constructTree(TREE_SIZE);
69
+ keepRunning = state.timeBatch(() => {
70
+ for (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {
71
+ endTree.insertSegments(i, [TextSegment.make("a")], endTree.localPerspective, { seq: i + 1, clientId: 0 }, { op: { type: MergeTreeDeltaType.INSERT } });
72
+ }
73
+ });
74
+ } while (keepRunning);
75
+ },
76
+ }),
64
77
  });
65
78
  });
66
79
  //# sourceMappingURL=Insertion.perf.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Insertion.perf.spec.js","sourceRoot":"","sources":["../../src/test/Insertion.perf.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\n\nimport { MergeTree } from \"../mergeTree.js\";\nimport { MergeTreeDeltaType } from \"../ops.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nfunction constructTree(numOfSegments: number): MergeTree {\n\tconst mergeTree = new MergeTree();\n\tfor (let i = 0; i < numOfSegments; i++) {\n\t\tmergeTree.insertSegments(\n\t\t\t0,\n\t\t\t[TextSegment.make(\"a\")],\n\t\t\tmergeTree.localPerspective,\n\t\t\t{ seq: i, clientId: 0 },\n\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t);\n\t}\n\treturn mergeTree;\n}\n\nconst TREE_SIZE: number = 7500;\n\ndescribe(\"MergeTree insertion\", () => {\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"insert into empty tree\",\n\t\tbenchmarkFn: () => {\n\t\t\tconst emptyTree = new MergeTree();\n\t\t\temptyTree.insertSegments(\n\t\t\t\t0,\n\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\temptyTree.localPerspective,\n\t\t\t\t{ seq: 0, clientId: 0 },\n\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t);\n\t\t},\n\t});\n\n\tlet startTree = constructTree(TREE_SIZE);\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"insert at start of large tree\",\n\t\tbenchmarkFn: () => {\n\t\t\tfor (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {\n\t\t\t\tstartTree.insertSegments(\n\t\t\t\t\t0,\n\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\tstartTree.localPerspective,\n\t\t\t\t\t{ seq: i + 1, clientId: 0 },\n\t\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tbeforeEachBatch: () => {\n\t\t\tstartTree = constructTree(TREE_SIZE);\n\t\t},\n\t});\n\n\tlet middleTree = constructTree(TREE_SIZE);\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"insert at middle of large tree\",\n\t\tbenchmarkFn: () => {\n\t\t\tfor (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {\n\t\t\t\tmiddleTree.insertSegments(\n\t\t\t\t\tTREE_SIZE / 2,\n\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\tmiddleTree.localPerspective,\n\t\t\t\t\t{ seq: i + 1, clientId: 0 },\n\t\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tbeforeEachBatch: () => {\n\t\t\tmiddleTree = constructTree(TREE_SIZE);\n\t\t},\n\t});\n\n\tlet endTree = constructTree(TREE_SIZE);\n\tbenchmark({\n\t\ttype: BenchmarkType.Measurement,\n\t\ttitle: \"insert at end of large tree\",\n\t\tbenchmarkFn: () => {\n\t\t\tfor (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {\n\t\t\t\tendTree.insertSegments(\n\t\t\t\t\ti,\n\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\tendTree.localPerspective,\n\t\t\t\t\t{ seq: i + 1, clientId: 0 },\n\t\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tbeforeEachBatch: () => {\n\t\t\tendTree = constructTree(TREE_SIZE);\n\t\t},\n\t});\n});\n"]}
1
+ {"version":3,"file":"Insertion.perf.spec.js","sourceRoot":"","sources":["../../src/test/Insertion.perf.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { benchmarkDuration, benchmarkIt } from \"@fluid-tools/benchmark\";\n\nimport { MergeTree } from \"../mergeTree.js\";\nimport { MergeTreeDeltaType } from \"../ops.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nfunction constructTree(numOfSegments: number): MergeTree {\n\tconst mergeTree = new MergeTree();\n\tfor (let i = 0; i < numOfSegments; i++) {\n\t\tmergeTree.insertSegments(\n\t\t\t0,\n\t\t\t[TextSegment.make(\"a\")],\n\t\t\tmergeTree.localPerspective,\n\t\t\t{ seq: i, clientId: 0 },\n\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t);\n\t}\n\treturn mergeTree;\n}\n\nconst TREE_SIZE: number = 7500;\n\ndescribe(\"MergeTree insertion\", () => {\n\tbenchmarkIt({\n\t\ttitle: \"insert into empty tree\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFn: () => {\n\t\t\t\tconst emptyTree = new MergeTree();\n\t\t\t\temptyTree.insertSegments(\n\t\t\t\t\t0,\n\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\temptyTree.localPerspective,\n\t\t\t\t\t{ seq: 0, clientId: 0 },\n\t\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t\t);\n\t\t\t},\n\t\t}),\n\t});\n\n\tbenchmarkIt({\n\t\ttitle: \"insert at start of large tree\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tlet startTree = constructTree(TREE_SIZE);\n\t\t\t\tlet keepRunning: boolean;\n\t\t\t\tdo {\n\t\t\t\t\tstartTree = constructTree(TREE_SIZE);\n\t\t\t\t\tkeepRunning = state.timeBatch(() => {\n\t\t\t\t\t\tfor (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {\n\t\t\t\t\t\t\tstartTree.insertSegments(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\t\t\t\tstartTree.localPerspective,\n\t\t\t\t\t\t\t\t{ seq: i + 1, clientId: 0 },\n\t\t\t\t\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} while (keepRunning);\n\t\t\t},\n\t\t}),\n\t});\n\n\tbenchmarkIt({\n\t\ttitle: \"insert at middle of large tree\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tlet middleTree = constructTree(TREE_SIZE);\n\t\t\t\tlet keepRunning: boolean;\n\t\t\t\tdo {\n\t\t\t\t\tmiddleTree = constructTree(TREE_SIZE);\n\t\t\t\t\tkeepRunning = state.timeBatch(() => {\n\t\t\t\t\t\tfor (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {\n\t\t\t\t\t\t\tmiddleTree.insertSegments(\n\t\t\t\t\t\t\t\tTREE_SIZE / 2,\n\t\t\t\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\t\t\t\tmiddleTree.localPerspective,\n\t\t\t\t\t\t\t\t{ seq: i + 1, clientId: 0 },\n\t\t\t\t\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} while (keepRunning);\n\t\t\t},\n\t\t}),\n\t});\n\n\tbenchmarkIt({\n\t\ttitle: \"insert at end of large tree\",\n\t\t...benchmarkDuration({\n\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\tlet endTree = constructTree(TREE_SIZE);\n\t\t\t\tlet keepRunning: boolean;\n\t\t\t\tdo {\n\t\t\t\t\tendTree = constructTree(TREE_SIZE);\n\t\t\t\t\tkeepRunning = state.timeBatch(() => {\n\t\t\t\t\t\tfor (let i = TREE_SIZE; i < TREE_SIZE + 25; i++) {\n\t\t\t\t\t\t\tendTree.insertSegments(\n\t\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\t\t\t\tendTree.localPerspective,\n\t\t\t\t\t\t\t\t{ seq: i + 1, clientId: 0 },\n\t\t\t\t\t\t\t\t{ op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} while (keepRunning);\n\t\t\t},\n\t\t}),\n\t});\n});\n"]}
@@ -2,56 +2,59 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { BenchmarkType, benchmark } from "@fluid-tools/benchmark";
5
+ import { benchmarkDuration, benchmarkIt } from "@fluid-tools/benchmark";
6
6
  import { MergeTree } from "../mergeTree.js";
7
7
  import { MergeTreeDeltaType } from "../ops.js";
8
8
  import { PriorPerspective } from "../perspective.js";
9
9
  import { TextSegment } from "../textSegment.js";
10
10
  describe("MergeTree partial lengths", () => {
11
- const originalIncrementalUpdate = MergeTree.options.incrementalUpdate;
12
11
  for (const incremental of [true, false]) {
13
- benchmark({
14
- type: BenchmarkType.Measurement,
12
+ benchmarkIt({
15
13
  title: `incremental updates = ${incremental}`,
16
14
  category: "partial lengths",
17
- before: () => {
18
- MergeTree.options.incrementalUpdate = incremental;
19
- },
20
- benchmarkFn: () => {
21
- const mergeTree = new MergeTree();
22
- const clientId = 0;
23
- let i = 1;
24
- for (; i < 1001; i++) {
25
- const stamp = {
26
- seq: i,
27
- clientId,
28
- };
29
- mergeTree.insertSegments(0, [TextSegment.make("a")], new PriorPerspective(i, clientId), stamp, {
30
- op: { type: MergeTreeDeltaType.INSERT },
31
- });
32
- }
33
- for (; i < 2001; i++) {
34
- const stamp = {
35
- seq: i,
36
- clientId,
37
- };
38
- mergeTree.markRangeRemoved(i - 1001, i - 1000, new PriorPerspective(i, clientId), stamp, {
39
- op: { type: MergeTreeDeltaType.REMOVE },
40
- });
41
- }
42
- for (; i < 3001; i++) {
43
- const stamp = {
44
- seq: i,
45
- clientId,
46
- };
47
- mergeTree.insertSegments(0, [TextSegment.make("a")], new PriorPerspective(i, clientId), stamp, {
48
- op: { type: MergeTreeDeltaType.INSERT },
49
- });
50
- }
51
- },
52
- after: () => {
53
- MergeTree.options.incrementalUpdate = originalIncrementalUpdate;
54
- },
15
+ ...benchmarkDuration({
16
+ benchmarkFnCustom: async (state) => {
17
+ const originalIncrementalUpdate = MergeTree.options.incrementalUpdate;
18
+ MergeTree.options.incrementalUpdate = incremental;
19
+ try {
20
+ state.timeAllBatches(() => {
21
+ const mergeTree = new MergeTree();
22
+ const clientId = 0;
23
+ let i = 1;
24
+ for (; i < 1001; i++) {
25
+ const stamp = {
26
+ seq: i,
27
+ clientId,
28
+ };
29
+ mergeTree.insertSegments(0, [TextSegment.make("a")], new PriorPerspective(i, clientId), stamp, {
30
+ op: { type: MergeTreeDeltaType.INSERT },
31
+ });
32
+ }
33
+ for (; i < 2001; i++) {
34
+ const stamp = {
35
+ seq: i,
36
+ clientId,
37
+ };
38
+ mergeTree.markRangeRemoved(i - 1001, i - 1000, new PriorPerspective(i, clientId), stamp, {
39
+ op: { type: MergeTreeDeltaType.REMOVE },
40
+ });
41
+ }
42
+ for (; i < 3001; i++) {
43
+ const stamp = {
44
+ seq: i,
45
+ clientId,
46
+ };
47
+ mergeTree.insertSegments(0, [TextSegment.make("a")], new PriorPerspective(i, clientId), stamp, {
48
+ op: { type: MergeTreeDeltaType.INSERT },
49
+ });
50
+ }
51
+ });
52
+ }
53
+ finally {
54
+ MergeTree.options.incrementalUpdate = originalIncrementalUpdate;
55
+ }
56
+ },
57
+ }),
55
58
  });
56
59
  }
57
60
  });
@@ -1 +1 @@
1
- {"version":3,"file":"PartialLengths.perf.spec.js","sourceRoot":"","sources":["../../src/test/PartialLengths.perf.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IAC1C,MAAM,yBAAyB,GAAY,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC;IAE/E,KAAK,MAAM,WAAW,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QACzC,SAAS,CAAC;YACT,IAAI,EAAE,aAAa,CAAC,WAAW;YAC/B,KAAK,EAAE,yBAAyB,WAAW,EAAE;YAC7C,QAAQ,EAAE,iBAAiB;YAC3B,MAAM,EAAE,GAAG,EAAE;gBACZ,SAAS,CAAC,OAAO,CAAC,iBAAiB,GAAG,WAAW,CAAC;YACnD,CAAC;YACD,WAAW,EAAE,GAAG,EAAE;gBACjB,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;gBAElC,MAAM,QAAQ,GAAG,CAAC,CAAC;gBACnB,IAAI,CAAC,GAAG,CAAC,CAAC;gBACV,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtB,MAAM,KAAK,GAAmB;wBAC7B,GAAG,EAAE,CAAC;wBACN,QAAQ;qBACR,CAAC;oBACF,SAAS,CAAC,cAAc,CACvB,CAAC,EACD,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvB,IAAI,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,EACjC,KAAK,EACL;wBACC,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE;qBACvC,CACD,CAAC;gBACH,CAAC;gBAED,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtB,MAAM,KAAK,GAAmB;wBAC7B,GAAG,EAAE,CAAC;wBACN,QAAQ;qBACR,CAAC;oBACF,SAAS,CAAC,gBAAgB,CACzB,CAAC,GAAG,IAAI,EACR,CAAC,GAAG,IAAI,EACR,IAAI,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,EACjC,KAAK,EACL;wBACC,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE;qBACvC,CACD,CAAC;gBACH,CAAC;gBAED,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtB,MAAM,KAAK,GAAmB;wBAC7B,GAAG,EAAE,CAAC;wBACN,QAAQ;qBACR,CAAC;oBACF,SAAS,CAAC,cAAc,CACvB,CAAC,EACD,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvB,IAAI,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,EACjC,KAAK,EACL;wBACC,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE;qBACvC,CACD,CAAC;gBACH,CAAC;YACF,CAAC;YACD,KAAK,EAAE,GAAG,EAAE;gBACX,SAAS,CAAC,OAAO,CAAC,iBAAiB,GAAG,yBAAyB,CAAC;YACjE,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\n\nimport { MergeTree } from \"../mergeTree.js\";\nimport { MergeTreeDeltaType } from \"../ops.js\";\nimport { PriorPerspective } from \"../perspective.js\";\nimport type { OperationStamp } from \"../stamps.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\ndescribe(\"MergeTree partial lengths\", () => {\n\tconst originalIncrementalUpdate: boolean = MergeTree.options.incrementalUpdate;\n\n\tfor (const incremental of [true, false]) {\n\t\tbenchmark({\n\t\t\ttype: BenchmarkType.Measurement,\n\t\t\ttitle: `incremental updates = ${incremental}`,\n\t\t\tcategory: \"partial lengths\",\n\t\t\tbefore: () => {\n\t\t\t\tMergeTree.options.incrementalUpdate = incremental;\n\t\t\t},\n\t\t\tbenchmarkFn: () => {\n\t\t\t\tconst mergeTree = new MergeTree();\n\n\t\t\t\tconst clientId = 0;\n\t\t\t\tlet i = 1;\n\t\t\t\tfor (; i < 1001; i++) {\n\t\t\t\t\tconst stamp: OperationStamp = {\n\t\t\t\t\t\tseq: i,\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t};\n\t\t\t\t\tmergeTree.insertSegments(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\t\tnew PriorPerspective(i, clientId),\n\t\t\t\t\t\tstamp,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\top: { type: MergeTreeDeltaType.INSERT },\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfor (; i < 2001; i++) {\n\t\t\t\t\tconst stamp: OperationStamp = {\n\t\t\t\t\t\tseq: i,\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t};\n\t\t\t\t\tmergeTree.markRangeRemoved(\n\t\t\t\t\t\ti - 1001,\n\t\t\t\t\t\ti - 1000,\n\t\t\t\t\t\tnew PriorPerspective(i, clientId),\n\t\t\t\t\t\tstamp,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\top: { type: MergeTreeDeltaType.REMOVE },\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tfor (; i < 3001; i++) {\n\t\t\t\t\tconst stamp: OperationStamp = {\n\t\t\t\t\t\tseq: i,\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t};\n\t\t\t\t\tmergeTree.insertSegments(\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\t\tnew PriorPerspective(i, clientId),\n\t\t\t\t\t\tstamp,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\top: { type: MergeTreeDeltaType.INSERT },\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t\tafter: () => {\n\t\t\t\tMergeTree.options.incrementalUpdate = originalIncrementalUpdate;\n\t\t\t},\n\t\t});\n\t}\n});\n"]}
1
+ {"version":3,"file":"PartialLengths.perf.spec.js","sourceRoot":"","sources":["../../src/test/PartialLengths.perf.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IAC1C,KAAK,MAAM,WAAW,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QACzC,WAAW,CAAC;YACX,KAAK,EAAE,yBAAyB,WAAW,EAAE;YAC7C,QAAQ,EAAE,iBAAiB;YAC3B,GAAG,iBAAiB,CAAC;gBACpB,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;oBAClC,MAAM,yBAAyB,GAAY,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC;oBAC/E,SAAS,CAAC,OAAO,CAAC,iBAAiB,GAAG,WAAW,CAAC;oBAClD,IAAI,CAAC;wBACJ,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE;4BACzB,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;4BAElC,MAAM,QAAQ,GAAG,CAAC,CAAC;4BACnB,IAAI,CAAC,GAAG,CAAC,CAAC;4BACV,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gCACtB,MAAM,KAAK,GAAmB;oCAC7B,GAAG,EAAE,CAAC;oCACN,QAAQ;iCACR,CAAC;gCACF,SAAS,CAAC,cAAc,CACvB,CAAC,EACD,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvB,IAAI,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,EACjC,KAAK,EACL;oCACC,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE;iCACvC,CACD,CAAC;4BACH,CAAC;4BAED,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gCACtB,MAAM,KAAK,GAAmB;oCAC7B,GAAG,EAAE,CAAC;oCACN,QAAQ;iCACR,CAAC;gCACF,SAAS,CAAC,gBAAgB,CACzB,CAAC,GAAG,IAAI,EACR,CAAC,GAAG,IAAI,EACR,IAAI,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,EACjC,KAAK,EACL;oCACC,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE;iCACvC,CACD,CAAC;4BACH,CAAC;4BAED,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gCACtB,MAAM,KAAK,GAAmB;oCAC7B,GAAG,EAAE,CAAC;oCACN,QAAQ;iCACR,CAAC;gCACF,SAAS,CAAC,cAAc,CACvB,CAAC,EACD,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvB,IAAI,gBAAgB,CAAC,CAAC,EAAE,QAAQ,CAAC,EACjC,KAAK,EACL;oCACC,EAAE,EAAE,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE;iCACvC,CACD,CAAC;4BACH,CAAC;wBACF,CAAC,CAAC,CAAC;oBACJ,CAAC;4BAAS,CAAC;wBACV,SAAS,CAAC,OAAO,CAAC,iBAAiB,GAAG,yBAAyB,CAAC;oBACjE,CAAC;gBACF,CAAC;aACD,CAAC;SACF,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { benchmarkDuration, benchmarkIt } from \"@fluid-tools/benchmark\";\n\nimport { MergeTree } from \"../mergeTree.js\";\nimport { MergeTreeDeltaType } from \"../ops.js\";\nimport { PriorPerspective } from \"../perspective.js\";\nimport type { OperationStamp } from \"../stamps.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\ndescribe(\"MergeTree partial lengths\", () => {\n\tfor (const incremental of [true, false]) {\n\t\tbenchmarkIt({\n\t\t\ttitle: `incremental updates = ${incremental}`,\n\t\t\tcategory: \"partial lengths\",\n\t\t\t...benchmarkDuration({\n\t\t\t\tbenchmarkFnCustom: async (state) => {\n\t\t\t\t\tconst originalIncrementalUpdate: boolean = MergeTree.options.incrementalUpdate;\n\t\t\t\t\tMergeTree.options.incrementalUpdate = incremental;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tstate.timeAllBatches(() => {\n\t\t\t\t\t\t\tconst mergeTree = new MergeTree();\n\n\t\t\t\t\t\t\tconst clientId = 0;\n\t\t\t\t\t\t\tlet i = 1;\n\t\t\t\t\t\t\tfor (; i < 1001; i++) {\n\t\t\t\t\t\t\t\tconst stamp: OperationStamp = {\n\t\t\t\t\t\t\t\t\tseq: i,\n\t\t\t\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tmergeTree.insertSegments(\n\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\t\t\t\t\tnew PriorPerspective(i, clientId),\n\t\t\t\t\t\t\t\t\tstamp,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\top: { type: MergeTreeDeltaType.INSERT },\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfor (; i < 2001; i++) {\n\t\t\t\t\t\t\t\tconst stamp: OperationStamp = {\n\t\t\t\t\t\t\t\t\tseq: i,\n\t\t\t\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tmergeTree.markRangeRemoved(\n\t\t\t\t\t\t\t\t\ti - 1001,\n\t\t\t\t\t\t\t\t\ti - 1000,\n\t\t\t\t\t\t\t\t\tnew PriorPerspective(i, clientId),\n\t\t\t\t\t\t\t\t\tstamp,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\top: { type: MergeTreeDeltaType.REMOVE },\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfor (; i < 3001; i++) {\n\t\t\t\t\t\t\t\tconst stamp: OperationStamp = {\n\t\t\t\t\t\t\t\t\tseq: i,\n\t\t\t\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tmergeTree.insertSegments(\n\t\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t\t[TextSegment.make(\"a\")],\n\t\t\t\t\t\t\t\t\tnew PriorPerspective(i, clientId),\n\t\t\t\t\t\t\t\t\tstamp,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\top: { type: MergeTreeDeltaType.INSERT },\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tMergeTree.options.incrementalUpdate = originalIncrementalUpdate;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}),\n\t\t});\n\t}\n});\n"]}