Skip to content

Commit 779a06a

Browse files
committed
perf: Use charCodeAt instead of TextEncoder for improved UTF string comparison performance.
1 parent 4e6a5c6 commit 779a06a

File tree

3 files changed

+10
-15
lines changed

3 files changed

+10
-15
lines changed

packages/firestore/src/model/path.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { Integer } from '@firebase/webchannel-wrapper/bloom-blob';
1919

2020
import { debugAssert, fail } from '../util/assert';
2121
import { Code, FirestoreError } from '../util/error';
22-
import { primitiveComparator, compareUtf8Strings } from '../util/misc';
22+
import { primitiveComparator, compareUtf16Strings } from '../util/misc';
2323

2424
export const DOCUMENT_KEY_NAME = '__name__';
2525

@@ -202,7 +202,7 @@ abstract class BasePath<B extends BasePath<B>> {
202202
);
203203
} else {
204204
// both non-numeric
205-
return compareUtf8Strings(lhs, rhs);
205+
return compareUtf16Strings(lhs, rhs);
206206
}
207207
}
208208

packages/firestore/src/model/values.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { fail } from '../util/assert';
2828
import {
2929
arrayEquals,
3030
primitiveComparator,
31-
compareUtf8Strings
31+
compareUtf16Strings
3232
} from '../util/misc';
3333
import { forEach, objectSize } from '../util/obj';
3434
import { isNegativeZero } from '../util/types';
@@ -255,7 +255,7 @@ export function valueCompare(left: Value, right: Value): number {
255255
getLocalWriteTime(right)
256256
);
257257
case TypeOrder.StringValue:
258-
return compareUtf8Strings(left.stringValue!, right.stringValue!);
258+
return compareUtf16Strings(left.stringValue!, right.stringValue!);
259259
case TypeOrder.BlobValue:
260260
return compareBlobs(left.bytesValue!, right.bytesValue!);
261261
case TypeOrder.RefValue:
@@ -404,7 +404,7 @@ function compareMaps(left: MapValue, right: MapValue): number {
404404
rightKeys.sort();
405405

406406
for (let i = 0; i < leftKeys.length && i < rightKeys.length; ++i) {
407-
const keyCompare = compareUtf8Strings(leftKeys[i], rightKeys[i]);
407+
const keyCompare = compareUtf16Strings(leftKeys[i], rightKeys[i]);
408408
if (keyCompare !== 0) {
409409
return keyCompare;
410410
}

packages/firestore/src/util/misc.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,15 @@ export interface Equatable<T> {
7575
isEqual(other: T): boolean;
7676
}
7777

78-
/** Compare strings in UTF-8 encoded byte order */
79-
export function compareUtf8Strings(left: string, right: string): number {
80-
// Convert the string to UTF-8 encoded bytes
81-
const encodedLeft = newTextEncoder().encode(left);
82-
const encodedRight = newTextEncoder().encode(right);
83-
84-
for (let i = 0; i < Math.min(encodedLeft.length, encodedRight.length); i++) {
85-
const comparison = primitiveComparator(encodedLeft[i], encodedRight[i]);
78+
/** Compare strings in UTF-16 encoded byte order */
79+
export function compareUtf16Strings(left: string, right: string): number {
80+
for (let i = 0; i < Math.min(left.length, right.length); i++) {
81+
const comparison = primitiveComparator(left.charCodeAt(i), right.charCodeAt(i));
8682
if (comparison !== 0) {
8783
return comparison;
8884
}
8985
}
90-
91-
return primitiveComparator(encodedLeft.length, encodedRight.length);
86+
return primitiveComparator(left.length, right.length);
9287
}
9388

9489
export interface Iterable<V> {

0 commit comments

Comments
 (0)