Skip to content

Commit f747972

Browse files
committed
chore: wip
1 parent 4b45292 commit f747972

6 files changed

Lines changed: 196 additions & 134 deletions

File tree

README.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -384,51 +384,51 @@ dtsx produces **sound** types (correctly widened for mutable containers) while p
384384

385385
## Benchmarks
386386

387-
Benchmarked on Apple M3 Pro, macOS _(bun 1.3.10, arm64-darwin)_. Run `bun benchmark/index.ts` to reproduce.
387+
Benchmarked on Apple M3 Pro, macOS _(bun 1.3.11, arm64-darwin)_. Run `bun benchmark/index.ts` to reproduce.
388388

389389
### In-Process API — Cached
390390

391391
_Smart caching (hash check + cache hit) for watch mode, incremental builds, and CI._
392392

393393
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
394394
|------|-------------------|---------------------|--------------------|--------------------|
395-
| **dtsx (cached)** | **0.95 µs** | **2.16 µs** | **19.84 µs** | **105.83 µs** |
396-
| zig-dtsx | 4.60 µs _(4.8x)_ | 11.27 µs _(5.2x)_ | 26.75 µs _(1.3x)_ | 230.91 µs _(2.2x)_ |
397-
| oxc-transform | 6.76 µs _(7.1x)_ | 20.54 µs _(9.5x)_ | 79.54 µs _(4.0x)_ | 519.44 µs _(4.9x)_ |
398-
| tsc | 194.34 µs _(205x)_ | 438.12 µs _(203x)_ | 1.14 ms _(57x)_ | 4.20 ms _(40x)_ |
395+
| **dtsx (cached)** | **97.81 ns** | **162.55 ns** | **376.39 ns** | **1.43 µs** |
396+
| zig-dtsx | 3.43 µs _(35.0x)_ | 7.16 µs _(44.0x)_ | 22.00 µs _(58.5x)_ | 147.21 µs _(103.0x)_ |
397+
| oxc-transform | 7.35 µs _(75.1x)_ | 22.66 µs _(139.4x)_ | 85.77 µs _(227.9x)_ | 558.72 µs _(390.7x)_ |
398+
| tsc | 236.82 µs _(2421x)_ | 463.06 µs _(2849x)_ | 1.53 ms _(4065x)_ | 4.66 ms _(3259x)_ |
399399

400400
### In-Process API — No Cache
401401

402402
_Raw single-transform comparison (cache cleared every iteration)._
403403

404404
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
405405
|------|-------------------|---------------------|--------------------|--------------------|
406-
| **zig-dtsx** | **4.68 µs** | **11.43 µs** | **27.89 µs** | **230.32 µs** |
407-
| oxc-transform | 6.95 µs _(1.5x)_ | 21.05 µs _(1.8x)_ | 81.46 µs _(2.9x)_ | 519.01 µs _(2.3x)_ |
408-
| dtsx (no-cache) | 10.42 µs _(2.2x)_ | 23.06 µs _(2.0x)_ | 67.79 µs _(2.4x)_ | 400.81 µs _(1.7x)_ |
409-
| tsc | 155.16 µs _(33x)_ | 389.90 µs _(34x)_ | 918.21 µs _(33x)_ | 3.82 ms _(17x)_ |
406+
| **zig-dtsx** | **3.37 µs** | **7.05 µs** | **21.89 µs** | **144.89 µs** |
407+
| oxc-transform | 7.36 µs _(2.2x)_ | 21.91 µs _(3.1x)_ | 89.66 µs _(4.1x)_ | 560.86 µs _(3.9x)_ |
408+
| dtsx (no-cache) | 15.52 µs _(4.6x)_ | 34.06 µs _(4.8x)_ | 81.96 µs _(3.7x)_ | 573.92 µs _(4.0x)_ |
409+
| tsc | 169.69 µs _(50.4x)_ | 410.31 µs _(58.2x)_ | 1.03 ms _(47.1x)_ | 4.02 ms _(27.7x)_ |
410410

411411
### CLI — Single File
412412

413413
_Compiled native binaries via subprocess._
414414

415415
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
416416
|------|-------------------|---------------------|--------------------|--------------------|
417-
| **zig-dtsx** | **2.32 ms** | **2.31 ms** | **2.42 ms** | **2.46 ms** |
418-
| oxc | 16.51 ms _(7.1x)_ | 15.71 ms _(6.8x)_ | 16.41 ms _(6.8x)_ | 16.14 ms _(6.6x)_ |
419-
| dtsx | 29.42 ms _(12.7x)_ | 29.36 ms _(12.7x)_ | 30.96 ms _(12.8x)_ | 32.30 ms _(13.1x)_ |
420-
| tsgo | 38.70 ms _(16.7x)_ | 41.97 ms _(18.2x)_ | 42.09 ms _(17.4x)_ | 52.83 ms _(21.5x)_ |
421-
| tsc | 347.31 ms _(150x)_ | 374.30 ms _(162x)_ | 376.76 ms _(156x)_ | 403.00 ms _(164x)_ |
417+
| **zig-dtsx** | **2.69 ms** | **2.35 ms** | **2.28 ms** | **3.14 ms** |
418+
| oxc | 17.08 ms _(6.3x)_ | 17.12 ms _(7.3x)_ | 17.95 ms _(7.9x)_ | 17.69 ms _(5.6x)_ |
419+
| dtsx | 33.42 ms _(12.4x)_ | 34.09 ms _(14.5x)_ | 34.41 ms _(15.1x)_ | 36.34 ms _(11.6x)_ |
420+
| tsgo | 40.53 ms _(15.1x)_ | 44.10 ms _(18.8x)_ | 44.39 ms _(19.5x)_ | 57.77 ms _(18.4x)_ |
421+
| tsc | 384.25 ms _(142.8x)_ | 407.51 ms _(173.4x)_ | 418.81 ms _(183.7x)_ | 454.74 ms _(144.8x)_ |
422422

423423
### Multi-File Project
424424

425425
| Tool | 50 files | 100 files | 500 files |
426426
|------|----------|-----------|-----------|
427-
| **zig-dtsx** | **12.16 ms** | **23.23 ms** | **109.33 ms** |
428-
| oxc | 35.38 ms _(2.9x)_ | 58.62 ms _(2.5x)_ | 402.32 ms _(3.7x)_ |
429-
| dtsx | 55.21 ms _(4.5x)_ | 79.14 ms _(3.4x)_ | 281.40 ms _(2.6x)_ |
430-
| tsgo | 210.54 ms _(17.3x)_ | 413.69 ms _(17.8x)_ | 2.18 s _(20.0x)_ |
431-
| tsc | 774.44 ms _(63.7x)_ | 1.18 s _(50.6x)_ | 3.99 s _(36.5x)_ |
427+
| **zig-dtsx** | **18.10 ms** | **31.46 ms** | **~140 ms** |
428+
| oxc | 48.27 ms _(2.7x)_ | 79.00 ms _(2.5x)_ | ~365 ms _(2.6x)_ |
429+
| dtsx | 70.86 ms _(3.9x)_ | 360.34 ms _(11.5x)_ | ~540 ms _(3.9x)_ |
430+
| tsgo | 244.68 ms _(13.5x)_ | 419.65 ms _(13.3x)_ | - |
431+
| tsc | 871.48 ms _(48.1x)_ | - | - |
432432

433433
### Binary Size
434434

benchmark-summary.md

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,72 @@
11
## Benchmark Results
22

3-
**Platform:** darwin arm64 | **Runtime:** Bun 1.3.10 | **Date:** 2026-02-13
3+
**Platform:** darwin arm64 | **Runtime:** Bun 1.3.11 | **Date:** 2026-03-20
44

55
### In-Process API — Cached
66

77
_Smart caching (hash check + cache hit) for watch mode, incremental builds, and CI._
88

9-
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) | XXLarge (~2000 lines) | Huge (~5000 lines) |
10-
|------|------|------|------|------|------|------|
11-
| **dtsx (cached)** | 24.3 µs _(3.4x)_ | 19.3 µs _(2.3x)_ | 62.4 µs _(2.6x)_ | **96.5 µs** | 254.9 µs _(1.1x)_ | 578.0 µs _(1.0x)_ |
12-
| zig-dtsx | **7.2 µs** | **8.4 µs** | **24.4 µs** | 159.2 µs _(1.6x)_ | **223.8 µs** | **563.9 µs** |
13-
| oxc-transform | 8.3 µs _(1.1x)_ | 23.5 µs _(2.8x)_ | 93.0 µs _(3.8x)_ | 560.5 µs _(5.8x)_ | 390.0 µs _(1.7x)_ | 1.42 ms _(2.5x)_ |
14-
| tsc | 1.01 ms _(140.3x)_ | 1.26 ms _(149.8x)_ | 3.22 ms _(132.3x)_ | 5.90 ms _(61.1x)_ | 8.96 ms _(40.0x)_ | 18.11 ms _(32.1x)_ |
9+
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
10+
|------|------|------|------|------|
11+
| **dtsx (cached)** | **97.81 ns** | **162.55 ns** | **376.39 ns** | **1.43 µs** |
12+
| zig-dtsx | 3.43 µs _(35.0x)_ | 7.16 µs _(44.0x)_ | 22.00 µs _(58.5x)_ | 147.21 µs _(103.0x)_ |
13+
| oxc-transform | 7.35 µs _(75.1x)_ | 22.66 µs _(139.4x)_ | 85.77 µs _(227.9x)_ | 558.72 µs _(390.7x)_ |
14+
| tsc | 236.82 µs _(2421x)_ | 463.06 µs _(2849x)_ | 1.53 ms _(4065x)_ | 4.66 ms _(3259x)_ |
1515

1616
### In-Process API — No Cache
1717

1818
_Raw single-transform comparison (cache cleared every iteration)._
1919

20-
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) | XXLarge (~2000 lines) | Huge (~5000 lines) |
21-
|------|------|------|------|------|------|------|
22-
| **zig-dtsx** | **7.2 µs** | **8.4 µs** | **24.4 µs** | **159.2 µs** | **223.8 µs** | **563.9 µs** |
23-
| oxc-transform | 8.3 µs _(1.1x)_ | 23.5 µs _(2.8x)_ | 93.0 µs _(3.8x)_ | 560.5 µs _(3.5x)_ | 390.0 µs _(1.7x)_ | 1.42 ms _(2.5x)_ |
24-
| dtsx (no-cache) | 45.9 µs _(6.3x)_ | 71.4 µs _(8.5x)_ | 133.0 µs _(5.5x)_ | 671.1 µs _(4.2x)_ | 991.0 µs _(4.4x)_ | 2.44 ms _(4.3x)_ |
25-
| tsc | 1.01 ms _(140.3x)_ | 1.26 ms _(149.8x)_ | 3.22 ms _(132.3x)_ | 5.90 ms _(37.1x)_ | 8.96 ms _(40.0x)_ | 18.11 ms _(32.1x)_ |
20+
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
21+
|------|------|------|------|------|
22+
| **zig-dtsx** | **3.37 µs** | **7.05 µs** | **21.89 µs** | **144.89 µs** |
23+
| oxc-transform | 7.36 µs _(2.2x)_ | 21.91 µs _(3.1x)_ | 89.66 µs _(4.1x)_ | 560.86 µs _(3.9x)_ |
24+
| dtsx (no-cache) | 15.52 µs _(4.6x)_ | 34.06 µs _(4.8x)_ | 81.96 µs _(3.7x)_ | 573.92 µs _(4.0x)_ |
25+
| tsc | 169.69 µs _(50.4x)_ | 410.31 µs _(58.2x)_ | 1.03 ms _(47.1x)_ | 4.02 ms _(27.7x)_ |
2626

2727
> **Note:** tsgo (`@typescript/native-preview`) is CLI-only — no in-process API is available yet. Each measurement includes ~40ms process spawn overhead, so it is not directly comparable to the in-process tools above. Once tsgo ships an in-process API, it will be added to the tables.
2828
29+
### CLI — Single File
30+
31+
_Compiled native binaries via subprocess._
32+
33+
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
34+
|------|------|------|------|------|
35+
| **zig-dtsx** | **2.69 ms** | **2.35 ms** | **2.28 ms** | **3.14 ms** |
36+
| oxc | 17.08 ms _(6.3x)_ | 17.12 ms _(7.3x)_ | 17.95 ms _(7.9x)_ | 17.69 ms _(5.6x)_ |
37+
| dtsx | 33.42 ms _(12.4x)_ | 34.09 ms _(14.5x)_ | 34.41 ms _(15.1x)_ | 36.34 ms _(11.6x)_ |
38+
| tsgo | 40.53 ms _(15.1x)_ | 44.10 ms _(18.8x)_ | 44.39 ms _(19.5x)_ | 57.77 ms _(18.4x)_ |
39+
| tsc | 384.25 ms _(142.8x)_ | 407.51 ms _(173.4x)_ | 418.81 ms _(183.7x)_ | 454.74 ms _(144.8x)_ |
40+
2941
### Multi-File Project
3042

3143
_All tools processing files in-process sequentially._
3244

33-
| Tool | 50 files | 100 files |
34-
|------|------|------|
35-
| **zig-dtsx** | **2.32 ms** | **4.79 ms** |
36-
| dtsx | 8.77 ms _(3.8x)_ | 18.23 ms _(3.8x)_ |
37-
| oxc-transform | 8.45 ms _(3.6x)_ | 17.57 ms _(3.7x)_ |
38-
| tsc | 85.76 ms _(36.9x)_ | 171.33 ms _(35.7x)_ |
39-
40-
> _No previous benchmark found for regression comparison_
45+
| Tool | 50 files | 100 files | 500 files |
46+
|------|------|------|------|
47+
| **zig-dtsx** | **18.10 ms** | **31.46 ms** | **~140 ms** |
48+
| oxc | 48.27 ms _(2.7x)_ | 79.00 ms _(2.5x)_ | ~365 ms _(2.6x)_ |
49+
| dtsx | 70.86 ms _(3.9x)_ | 360.34 ms _(11.5x)_ | ~540 ms _(3.9x)_ |
50+
| tsgo | 244.68 ms _(13.5x)_ | 419.65 ms _(13.3x)_ | - |
51+
| tsc | 871.48 ms _(48.1x)_ | - | - |
4152

4253
### zig-dtsx vs oxc-transform
4354

4455
| Input Size | zig-dtsx | oxc-transform | Speedup |
4556
|-----------|----------|---------------|----------|
46-
| Small (~50 lines) | 7.2 µs | 8.3 µs | :green_circle: 1.14x |
47-
| Medium (~100 lines) | 8.4 µs | 23.5 µs | :green_circle: 2.79x |
48-
| Large (~330 lines) | 24.4 µs | 93.0 µs | :green_circle: 3.82x |
49-
| XLarge (~1050 lines) | 159.2 µs | 560.5 µs | :green_circle: 3.52x |
50-
| XXLarge (~2000 lines) | 223.8 µs | 390.0 µs | :green_circle: 1.74x |
51-
| Huge (~5000 lines) | 563.9 µs | 1.42 ms | :green_circle: 2.51x |
57+
| Small (~50 lines) | 3.37 µs | 7.36 µs | :green_circle: 2.18x |
58+
| Medium (~100 lines) | 7.05 µs | 21.91 µs | :green_circle: 3.11x |
59+
| Large (~330 lines) | 21.89 µs | 89.66 µs | :green_circle: 4.10x |
60+
| XLarge (~1050 lines) | 144.89 µs | 560.86 µs | :green_circle: 3.87x |
61+
62+
### dtsx (cached) vs oxc-transform
63+
64+
| Input Size | dtsx (cached) | oxc-transform | Speedup |
65+
|-----------|----------|---------------|----------|
66+
| Small (~50 lines) | 97.81 ns | 7.35 µs | :green_circle: 75x |
67+
| Medium (~100 lines) | 162.55 ns | 22.66 µs | :green_circle: 139x |
68+
| Large (~330 lines) | 376.39 ns | 85.77 µs | :green_circle: 228x |
69+
| XLarge (~1050 lines) | 1.43 µs | 558.72 µs | :green_circle: 391x |
5270

5371
<details>
5472
<summary><strong>Internal Benchmark Details</strong></summary>

packages/dtsx/src/processor/index.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ export {
9191

9292
const EXPORT_ITEMS_PATTERN = /export\s+(?:type\s+)?\{\s*([^}]+)\s*\}/
9393

94+
// Module-level cache for import priority patterns
95+
let _cachedImportOrder: string[] | null = null
96+
let _cachedPrioritySingle: string[] = []
97+
let _cachedPriorityDouble: string[] = []
98+
9499
/**
95100
* Process declarations and convert them to narrow DTS format
96101
*/
@@ -176,9 +181,17 @@ export function processDeclarations(
176181
// Extract exported items for tracking (using cached pattern)
177182
const match = exportText.match(EXPORT_ITEMS_PATTERN)
178183
if (match) {
179-
const items = match[1].split(',').map(item => item.trim())
180-
for (const item of items) {
181-
exportedItems.add(item)
184+
// Single-pass parsing: avoid split().map() allocation
185+
const rawItems = match[1]
186+
let itemStart = 0
187+
for (let i = 0; i <= rawItems.length; i++) {
188+
if (i === rawItems.length || rawItems.charCodeAt(i) === 44) {
189+
let s = itemStart, e = i
190+
while (s < e && rawItems.charCodeAt(s) <= 32) s++
191+
while (e > s && rawItems.charCodeAt(e - 1) <= 32) e--
192+
if (s < e) exportedItems.add(rawItems.slice(s, e))
193+
itemStart = i + 1
194+
}
182195
}
183196
}
184197

@@ -324,8 +337,13 @@ export function processDeclarations(
324337
// Pre-compute priority for each import into a Map (avoids re-scanning in O(n log n) comparator)
325338
const defaultPriority = importOrder.length
326339
if (processedImports.length > 1) {
327-
const prioritySingle = importOrder.map(p => `from '${p}`)
328-
const priorityDouble = importOrder.map(p => `from "${p}`)
340+
if (_cachedImportOrder !== importOrder) {
341+
_cachedImportOrder = importOrder
342+
_cachedPrioritySingle = importOrder.map(p => `from '${p}`)
343+
_cachedPriorityDouble = importOrder.map(p => `from "${p}`)
344+
}
345+
const prioritySingle = _cachedPrioritySingle
346+
const priorityDouble = _cachedPriorityDouble
329347
const priorityMap = new Map<string, number>()
330348
for (const imp of processedImports) {
331349
let p = defaultPriority

0 commit comments

Comments
 (0)