GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — feat: switch grisu2 float-to-string algorithm to hybrid of xjb & zmij algorithms by JairusSW · Pull Request #3025 · AssemblyScript/assemblyscript Conversation
|
| Types used | Base | PR | Increase |
|---|---|---|---|
f64 only |
4,122 B | 7,319 B | +3,197 B |
f32 only |
4,120 B | 5,690 B | +1,570 B |
| Both | 4,342 B | 10,690 B | +6,348 B |
With the default incremental runtime, the both-width module grows from 6,834 B to 13,248 B (+6,414 B). These small formatter-focused modules do not estimate whole-application growth. The generated string wrappers call shared buffered formatters; the exact-integer direct-allocation path adds specialized code.
Throughput on Node 24.22.1, x86-64 AMD EPYC 9V74, default incremental runtime, scalar builds: 4,096 inputs per bucket, 150,000 warmup operations, and medians of seven alternating base/PR samples of 400,000 operations. The timed loops run inside Wasm.
| Input bucket | API | Base, ns/value | PR, ns/value | Speedup |
|---|---|---|---|---|
| Small signed integers | f64 buffered |
43.6 | 10.1 | 4.31× |
| Small signed integers | f32 buffered |
46.1 | 9.8 | 4.71× |
| Small signed integers | f64 string |
89.6 | 50.6 | 1.77× |
| Small signed integers | f32 string |
85.1 | 48.4 | 1.76× |
| Ordinary decimals | f64 buffered |
52.5 | 38.6 | 1.36× |
| Ordinary decimals | f32 buffered |
55.0 | 27.5 | 2.00× |
| Ordinary decimals | f64 string |
96.0 | 96.4 | Effectively unchanged |
| Ordinary decimals | f32 string |
100.9 | 85.5 | 1.18× |
| Random finite bit patterns | f64 buffered |
82.9 | 48.0 | 1.73× |
| Random finite bit patterns | f32 buffered |
68.6 | 27.7 | 2.47× |
| Random finite bit patterns | f64 string |
132.1 | 93.1 | 1.42× |
| Random finite bit patterns | f32 string |
132.6 | 87.4 | 1.52× |
Ordinary decimals are nonintegral values roughly between −1,000 and +1,000, formed by dividing integers by 1,000. Gains are strongest for buffered formatting and integers; complete-string performance varies with workload. The 96.0 → 96.4 ns ordinary-decimal f64 result is effectively flat, not a meaningful measured regression.
A separate SIMD diagnostic run improved random-finite buffered formatting by 2.31× (f64) and 2.75× (f32) against its own interleaved baseline. Ordinary-decimal f64 string output improved by about 6% in that run.
Correctness validation at this revision includes exact BigInt binary32 rounding intervals with ties-to-even, the four formerly double-rounded f32 regressions, all four checked-in debug/release × scalar/SIMD configurations (556,880 exact output comparisons), 28-code-unit canaries, the float-array join allocation budget, and independent verification of all 618 cached powers. Independent review also checked 28,076 cases against C++ std::to_chars(float, scientific) and 12,384 additional boundary comparisons across the buffered, ordinary string, and low-level string paths. These are substantial checks, not an exhaustive proof over all floating-point bit patterns.
P.S. Sorry about the diff. Most of it is generated WAT fixtures.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Signed-off-by: Jairus Tanaka <[email protected]>
Signed-off-by: Jairus Tanaka <[email protected]>
Signed-off-by: Jairus Tanaka <[email protected]>
|
Just curious here, why the exception of a trailing .0? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Max and Dan made that decision so that floats are easily identifiable when converting them to a string. For example, you know that the string |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Can you rename xjb.ts to dtoa.ts and in comments mentioned about implementation based on xjb and zmij? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Co-authored-by: Max Graey <[email protected]>
Co-authored-by: Max Graey <[email protected]>
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Co-authored-by: Max Graey <[email protected]>
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Co-authored-by: Max Graey <[email protected]>
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Also plz add extra tests which cover new implementation-specific edge cases (I anready found a bug) and uncomment existing test cases which failed with grisu2 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…ript into jairus/switch-to-xjb
220f9c4 to
660bd25
Compare
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
[Task] Replace Grisu2 with Xjb for float-to-string conversion
There was an error while loading. Please reload this page.