Commit c9c3970
authored
perf(ts): cache decoded FSST shared dictionaries (#1512)
## Summary
MLT `SharedDict` columns store strings for multiple child property
columns in one dictionary corpus. When the corpus is FSST-compressed,
the TypeScript decoder exposes each child as a separate
`StringFsstDictionaryVector`.
Previously, the first access to each vector decoded the complete shared
FSST corpus again. Consumers such as MapLibre GL JS may access several
of these vectors while materializing properties for styles, filters, or
`queryRenderedFeatures()`.
This PR:
- Adds a benchmark for ordinary and shared FSST dictionary access.
- Creates one lazy decoded-dictionary cache per `SharedDict`.
- Shares that cache only between the vectors belonging to that group.
- Keeps ordinary FSST vectors on their existing direct decoding path.
- Ties the cache lifetime to the vectors and tile without a module-level
`WeakMap`.
- Tests that two vectors from one FSST `SharedDict` call `decodeFsst()`
only once.
#1505 makes this optimization slightly less relevant by preventing some
oversized shared-dictionary groups with little actual value overlap, but
beneficial `SharedDict` groups remain.
## Benchmark
The benchmark uses the real FSST dictionary from `14_8299_10748.mlt`,
which does not contain a `SharedDict`, to construct controlled
cold-access scenarios.
`xlarge.mlt` contains a real shared FSST dictionary, but reusing its
vectors would warm the cache after the first iteration. Re-decoding the
entire 5.4 MB tile for every iteration would make full-tile decoding
dominate the cache overhead being measured.
Node 24.11.1 results, averaging the mean latency from two runs:
| Cold access | Before | After | Result |
| --- | ---: | ---: | ---: |
| One ordinary FSST vector | 0.4117 ms | 0.4057 ms | No regression |
| Two ordinary FSST vectors | 0.8146 ms | 0.8192 ms | No regression |
| Two vectors from one `SharedDict` | 0.8048 ms | 0.4132 ms | 1.95×
faster |
| Five vectors from one `SharedDict` | 1.9826 ms | 0.4123 ms | 4.81×
faster |
## AI notice
This PR was developed with assistance from OpenAI Codex.1 parent 4bef5ee commit c9c3970
3 files changed
Lines changed: 123 additions & 6 deletions
File tree
- ts/src
- decoding
- vector/fsst-dictionary
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
15 | 18 | | |
16 | 19 | | |
17 | 20 | | |
| |||
204 | 207 | | |
205 | 208 | | |
206 | 209 | | |
| 210 | + | |
| 211 | + | |
207 | 212 | | |
208 | 213 | | |
209 | 214 | | |
| |||
259 | 264 | | |
260 | 265 | | |
261 | 266 | | |
| 267 | + | |
262 | 268 | | |
263 | 269 | | |
264 | 270 | | |
| |||
Lines changed: 95 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
Lines changed: 21 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
6 | 12 | | |
7 | 13 | | |
8 | 14 | | |
| |||
16 | 22 | | |
17 | 23 | | |
18 | 24 | | |
| 25 | + | |
| 26 | + | |
19 | 27 | | |
20 | 28 | | |
21 | 29 | | |
22 | 30 | | |
23 | 31 | | |
24 | 32 | | |
25 | | - | |
26 | | - | |
27 | | - | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
28 | 39 | | |
29 | | - | |
30 | | - | |
31 | 40 | | |
32 | 41 | | |
33 | 42 | | |
| |||
36 | 45 | | |
37 | 46 | | |
38 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
39 | 55 | | |
40 | 56 | | |
41 | 57 | | |
| |||
0 commit comments