Skip to content

Commit fdd2f28

Browse files
committed
tweaks
1 parent 4d57efe commit fdd2f28

File tree

3 files changed

+66
-15
lines changed

3 files changed

+66
-15
lines changed

benchmark/key-decoder.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* eslint-disable no-console */
2+
import { utf8EncodeJs, utf8Count, utf8DecodeJs, utf8DecodeTD } from "../src/utils/utf8";
3+
import { utf8DecodeWasm } from "../src/wasmFunctions";
4+
5+
// @ts-ignore
6+
import Benchmark from "benchmark";
7+
import { CachedKeyDecoder } from "../src/CachedKeyDecoder";
8+
9+
type InputType = {
10+
bytes: Uint8Array;
11+
byteLength: number;
12+
str: string;
13+
};
14+
15+
const keys: Array<InputType> = Object.keys(require("./benchmark-from-msgpack-lite-data.json")).map((str) => {
16+
const byteLength = utf8Count(str);
17+
const bytes = new Uint8Array(new ArrayBuffer(byteLength));
18+
19+
utf8EncodeJs(str, bytes, 0);
20+
21+
return { bytes, byteLength, str };
22+
});
23+
24+
for (const dataSet of [keys]) {
25+
const keyDecoder = new CachedKeyDecoder();
26+
27+
const suite = new Benchmark.Suite();
28+
29+
suite.add("utf8DecodeJs", () => {
30+
for (const data of dataSet) {
31+
if (utf8DecodeJs(data.bytes, 0, data.byteLength) !== data.str) {
32+
throw new Error("wrong result!");
33+
}
34+
}
35+
});
36+
37+
suite.add("CachedKeyDecoder", () => {
38+
for (const data of dataSet) {
39+
if (keyDecoder.decode(data.bytes, 0, data.byteLength) !== data.str) {
40+
throw new Error("wrong result!");
41+
}
42+
}
43+
});
44+
suite.on("cycle", (event: any) => {
45+
console.log(String(event.target));
46+
});
47+
48+
suite.run();
49+
}

src/CachedKeyDecoder.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { utf8DecodeJs } from "./utils/utf8";
33
interface KeyCacheRecord {
44
readonly bytes: Uint8Array;
55
readonly value: string;
6-
hits: number;
76
}
87

98
const DEFAULT_MAX_KEY_LENGTH = 16;
@@ -39,19 +38,21 @@ export class CachedKeyDecoder {
3938
continue FIND_CHUNK;
4039
}
4140
}
42-
43-
record.hits++;
4441
return record.value;
4542
}
4643
return null;
4744
}
4845

4946
private store(bytes: Uint8Array, value: string) {
5047
const records = this.caches[bytes.length - 1];
51-
const hits = 1;
52-
records.unshift({ bytes, value, hits });
53-
if (records.length > this.maxLengthPerKey) {
54-
records.pop();
48+
const record: KeyCacheRecord = { bytes, value };
49+
50+
if (records.length >= this.maxLengthPerKey) {
51+
// `records` are full!
52+
// Set `record` to a randomized position.
53+
records[(Math.random() * records.length) | 0] = record;
54+
} else {
55+
records.push(record);
5556
}
5657
}
5758

test/CachedKeyDecoder.test.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ describe("CachedKeyDecoder", () => {
3535
});
3636

3737
it("decodes strings with purging records", () => {
38-
const decoder = new CachedKeyDecoder(16, 2);
38+
const decoder = new CachedKeyDecoder(16, 4);
3939

40-
assert.deepStrictEqual(tryDecode(decoder, "foo"), "foo");
41-
assert.deepStrictEqual(tryDecode(decoder, "bar"), "bar");
40+
for (let i = 0; i < 100; i++) {
41+
assert.deepStrictEqual(tryDecode(decoder, "foo1"), "foo1");
42+
assert.deepStrictEqual(tryDecode(decoder, "foo2"), "foo2");
43+
assert.deepStrictEqual(tryDecode(decoder, "foo3"), "foo3");
44+
assert.deepStrictEqual(tryDecode(decoder, "foo4"), "foo4");
45+
assert.deepStrictEqual(tryDecode(decoder, "foo5"), "foo5");
46+
}
4247

43-
// the next `tryDecode()` should purge the cache of "foo"
44-
assert.deepStrictEqual(tryDecode(decoder, "baz"), "baz");
45-
46-
// with newly created an internal cache record
47-
assert.deepStrictEqual(tryDecode(decoder, "foo"), "foo");
48+
console.dir(decoder, { depth: 100 });
4849
});
4950
});
5051

0 commit comments

Comments
 (0)