Skip to content

Commit b2f78bf

Browse files
authored
perf: make arena 10% smaller; store 1 offset + some deltas (#31)
- [x] Measure before/after to see if it's actually faster - [x] Measure before/after to see if it actually uses less memory Performance remains the same but uses ~7% less memory while doing so.
1 parent 43f214c commit b2f78bf

File tree

1 file changed

+30
-22
lines changed

1 file changed

+30
-22
lines changed

src/arena.ts

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// CSS Data Arena - Single contiguous ArrayBuffer for all AST nodes
22
//
3-
// Each node occupies 44 bytes with the following layout:
3+
// Each node occupies 40 bytes with the following layout:
44
// Offset | Size | Field
55
// -------|------|-------------
66
// 0 | 1 | type
@@ -9,18 +9,18 @@
99
// 4 | 4 | startOffset
1010
// 8 | 2 | length
1111
// 10 | 2 | (padding)
12-
// 12 | 4 | contentStart (property name / at-rule name)
13-
// 16 | 2 | contentLength
14-
// 18 | 2 | (padding)
12+
// 12 | 2 | contentStartDelta (offset from startOffset, property name / at-rule name)
13+
// 14 | 2 | contentLength
14+
// 16 | 2 | valueStartDelta (offset from startOffset, declaration value / at-rule prelude)
15+
// 18 | 2 | valueLength
1516
// 20 | 4 | firstChild
1617
// 24 | 4 | lastChild
1718
// 28 | 4 | nextSibling
1819
// 32 | 4 | startLine
19-
// 36 | 4 | valueStart (declaration value / at-rule prelude)
20-
// 40 | 2 | valueLength
21-
// 42 | 2 | startColumn
20+
// 36 | 2 | startColumn
21+
// 38 | 2 | (padding)
2222

23-
let BYTES_PER_NODE = 44
23+
let BYTES_PER_NODE = 40
2424

2525
// Node type constants
2626
export const NODE_STYLESHEET = 1
@@ -160,14 +160,16 @@ export class CSSDataArena {
160160
return this.view.getUint16(this.node_offset(node_index) + 8, true)
161161
}
162162

163-
// Read content start offset
163+
// Read content start offset (stored as delta from startOffset)
164164
get_content_start(node_index: number): number {
165-
return this.view.getUint32(this.node_offset(node_index) + 12, true)
165+
const startOffset = this.get_start_offset(node_index)
166+
const delta = this.view.getUint16(this.node_offset(node_index) + 12, true)
167+
return startOffset + delta
166168
}
167169

168170
// Read content length
169171
get_content_length(node_index: number): number {
170-
return this.view.getUint16(this.node_offset(node_index) + 16, true)
172+
return this.view.getUint16(this.node_offset(node_index) + 14, true)
171173
}
172174

173175
// Read attribute operator (for NODE_SELECTOR_ATTRIBUTE)
@@ -202,17 +204,19 @@ export class CSSDataArena {
202204

203205
// Read start column
204206
get_start_column(node_index: number): number {
205-
return this.view.getUint16(this.node_offset(node_index) + 42, true)
207+
return this.view.getUint16(this.node_offset(node_index) + 36, true)
206208
}
207209

208-
// Read value start offset (declaration value / at-rule prelude)
210+
// Read value start offset (stored as delta from startOffset, declaration value / at-rule prelude)
209211
get_value_start(node_index: number): number {
210-
return this.view.getUint32(this.node_offset(node_index) + 36, true)
212+
const startOffset = this.get_start_offset(node_index)
213+
const delta = this.view.getUint16(this.node_offset(node_index) + 16, true)
214+
return startOffset + delta
211215
}
212216

213217
// Read value length
214218
get_value_length(node_index: number): number {
215-
return this.view.getUint16(this.node_offset(node_index) + 40, true)
219+
return this.view.getUint16(this.node_offset(node_index) + 18, true)
216220
}
217221

218222
// --- Write Methods ---
@@ -237,14 +241,16 @@ export class CSSDataArena {
237241
this.view.setUint16(this.node_offset(node_index) + 8, length, true)
238242
}
239243

240-
// Write content start offset
244+
// Write content start offset (stored as delta from startOffset)
241245
set_content_start(node_index: number, offset: number): void {
242-
this.view.setUint32(this.node_offset(node_index) + 12, offset, true)
246+
const startOffset = this.get_start_offset(node_index)
247+
const delta = offset - startOffset
248+
this.view.setUint16(this.node_offset(node_index) + 12, delta, true)
243249
}
244250

245251
// Write content length
246252
set_content_length(node_index: number, length: number): void {
247-
this.view.setUint16(this.node_offset(node_index) + 16, length, true)
253+
this.view.setUint16(this.node_offset(node_index) + 14, length, true)
248254
}
249255

250256
// Write attribute operator (for NODE_SELECTOR_ATTRIBUTE)
@@ -279,17 +285,19 @@ export class CSSDataArena {
279285

280286
// Write start column
281287
set_start_column(node_index: number, column: number): void {
282-
this.view.setUint16(this.node_offset(node_index) + 42, column, true)
288+
this.view.setUint16(this.node_offset(node_index) + 36, column, true)
283289
}
284290

285-
// Write value start offset (declaration value / at-rule prelude)
291+
// Write value start offset (stored as delta from startOffset, declaration value / at-rule prelude)
286292
set_value_start(node_index: number, offset: number): void {
287-
this.view.setUint32(this.node_offset(node_index) + 36, offset, true)
293+
const startOffset = this.get_start_offset(node_index)
294+
const delta = offset - startOffset
295+
this.view.setUint16(this.node_offset(node_index) + 16, delta, true)
288296
}
289297

290298
// Write value length
291299
set_value_length(node_index: number, length: number): void {
292-
this.view.setUint16(this.node_offset(node_index) + 40, length, true)
300+
this.view.setUint16(this.node_offset(node_index) + 18, length, true)
293301
}
294302

295303
// --- Node Creation ---

0 commit comments

Comments
 (0)