Skip to content

Commit 57a75a8

Browse files
committed
fix #2162: some numbers now print slightly smaller
1 parent bdee212 commit 57a75a8

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

CHANGELOG.md

+19
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,25 @@
6161

6262
And the reason lowering private members requires adjusting `super()` calls is because the injected private member initializers use `this`, which is only accessible after `super()` calls in the constructor.
6363

64+
* Print some large integers using hexadecimal when minifying ([#2162](https://github.com/evanw/esbuild/issues/2162))
65+
66+
When `--minify` is active, esbuild will now use one fewer byte to represent certain large integers:
67+
68+
```js
69+
// Original code
70+
x = 123456787654321;
71+
72+
// Old output (with --minify)
73+
x=123456787654321;
74+
75+
// New output (with --minify)
76+
x=0x704885f926b1;
77+
```
78+
79+
This works because a hexadecimal representation can be shorter than a decimal representation starting at around 10<sup>12</sup> and above.
80+
81+
_This optimization made me realize that there's probably an opportunity to optimize printed numbers for smaller gzipped size instead of or in addition to just optimizing for minimal uncompressed byte count. The gzip algorithm does better with repetitive sequences, so for example `0xFFFFFFFF` is probably a better representation than `4294967295` even though the byte counts are the same. As far as I know, no JavaScript minifier does this optimization yet. I don't know enough about how gzip works to know if this is a good idea or what the right metric for this might be._
82+
6483
* Add Linux ARM64 support for Deno ([#2156](https://github.com/evanw/esbuild/issues/2156))
6584

6685
This release adds Linux ARM64 support to esbuild's [Deno](https://deno.land/) API implementation, which allows esbuild to be used with Deno on a Raspberry Pi.

internal/js_printer/js_printer.go

+9
Original file line numberDiff line numberDiff line change
@@ -2788,6 +2788,15 @@ func (p *printer) printNonNegativeFloat(absValue float64) {
27882788
}
27892789
}
27902790

2791+
// Numbers in this range can potentially be printed with one fewer byte as hex
2792+
if p.options.MinifyWhitespace && absValue >= 1_000_000_000_000 && absValue <= 0xFFFF_FFFF_FFFF_FFFF {
2793+
if asInt := uint64(absValue); absValue == float64(asInt) {
2794+
if hex := strconv.FormatUint(asInt, 16); 2+len(hex) < len(result) {
2795+
result = append(append(result[:0], '0', 'x'), hex...)
2796+
}
2797+
}
2798+
}
2799+
27912800
p.printBytes(result)
27922801
}
27932802

internal/js_printer/js_printer_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,16 @@ func TestNumber(t *testing.T) {
262262
expectPrinted(t, "x = -0xffff_ffff_ffff_fbff", "x = -1844674407370955e4;\n")
263263
expectPrinted(t, "x = -0x1_0000_0000_0000_0000", "x = -18446744073709552e3;\n")
264264
expectPrinted(t, "x = -0x1_0000_0000_0000_1000", "x = -18446744073709556e3;\n")
265+
266+
// Check the hex vs. decimal decision boundary when minifying
267+
expectPrinted(t, "x = 999999999999", "x = 999999999999;\n")
268+
expectPrinted(t, "x = 1000000000001", "x = 1000000000001;\n")
269+
expectPrinted(t, "x = 0xFFFFFFFFFFFFF80", "x = 1152921504606846800;\n")
270+
expectPrinted(t, "x = 0x1000000000000000", "x = 1152921504606847e3;\n")
271+
expectPrintedMinify(t, "x = 999999999999", "x=999999999999;")
272+
expectPrintedMinify(t, "x = 1000000000001", "x=0xe8d4a51001;")
273+
expectPrintedMinify(t, "x = 0xFFFFFFFFFFFFF80", "x=0xfffffffffffff80;")
274+
expectPrintedMinify(t, "x = 0x1000000000000000", "x=1152921504606847e3;")
265275
}
266276

267277
func TestArray(t *testing.T) {

0 commit comments

Comments
 (0)