diff --git a/Makefile b/Makefile index d4da4d8..20cd9a6 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ fuzz-all: @sh scripts/fuzz-all.sh $(fuzzTime) bench: - @go test -bench=BenchmarkString -benchmem -benchmem -memprofile=mem.out -cpuprofile=cpu.out -run NONE + @go test -bench=BenchmarkGVString -benchmem -benchmem -memprofile=mem.out -cpuprofile=cpu.out -run NONE # https://stackoverflow.com/questions/6273608/how-to-pass-argument-to-makefile-from-command-line %: diff --git a/benchmarks/Makefile b/benchmarks/Makefile index e7d9d2f..87ce171 100644 --- a/benchmarks/Makefile +++ b/benchmarks/Makefile @@ -1,7 +1,7 @@ bench: # @go test -bench BenchmarkMarshalJSON -benchmem -memprofile mem.out -cpuprofile cpu.out -run NONE - @go test -bench BenchmarkParse -benchmem -count=10 -run NONE > new.txt + @go test -bench BenchmarkMarshalJSON -benchmem -count=10 -run NONE > new.txt bench-udec: @rm -f bench-udec.txt diff --git a/benchmarks/README.md b/benchmarks/README.md index a6fc5b1..7e16ba1 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -68,14 +68,14 @@ BenchmarkParse/1234567890-32 BenchmarkParse/0.1234567890123456879-32 44339668 26.45 ns/op 0 B/op 0 allocs/op BenchmarkParseFallBack/123456789123456789123456.1234567890123456-32 2805122 473.3 ns/op 192 B/op 6 allocs/op BenchmarkParseFallBack/111222333444555666777888999.1234567890123456789-32 2442004 500.8 ns/op 216 B/op 6 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 12797790 98.69 ns/op 48 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 18784728 57.20 ns/op 24 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 14577884 76.50 ns/op 48 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 41109242 40.02 ns/op 24 B/op 1 allocs/op BenchmarkStringFallBack/123456789123456789123456.1234567890123456-32 4147044 256.2 ns/op 208 B/op 4 allocs/op BenchmarkStringFallBack/111222333444555666777888999.1234567890123456789-32 3808071 313.3 ns/op 208 B/op 4 allocs/op # Marshal/Unmarshal -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 15796016 96.75 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 22017422 54.95 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 13965998 77.22 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 24039360 43.57 ns/op 24 B/op 1 allocs/op BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3445560 291.6 ns/op 320 B/op 5 allocs/op BenchmarkUnmarshalJSON/1234567890123456789.1234567890123456879-32 15943234 73.77 ns/op 0 B/op 0 allocs/op BenchmarkUnmarshalJSON/123456.123456-32 46983879 26.55 ns/op 0 B/op 0 allocs/op @@ -98,8 +98,8 @@ Parse/1234567890123456789.1234567890123456879-32 Parse/0.1234567890123456879-32 262.30n ± 17% 25.93n ± 3% -90.11% (p=0.000 n=10) ParseFallBack/123456789123456789123456.1234567890123456-32 373.2n ± 13% 418.3n ± 7% +12.08% (p=0.000 n=10) ParseFallBack/111222333444555666777888999.1234567890123456789-32 418.5n ± 5% 453.4n ± 9% +8.33% (p=0.003 n=10) -String/1234567890123456789.1234567890123456879-32 284.45n ± 26% 97.61n ± 11% -65.68% (p=0.000 n=10) -String/0.1234567890123456879-32 173.80n ± 15% 58.94n ± 15% -66.09% (p=0.000 n=10) +String/1234567890123456789.1234567890123456879-32 284.45n ± 26% 77.35n ± 10% -72.81% (p=0.000 n=10) +String/0.1234567890123456879-32 173.80n ± 15% 42.60n ± 6% -75.49% (p=0.000 n=10) StringFallBack/123456789123456789123456.1234567890123456-32 394.1n ± 15% 268.4n ± 22% -31.90% (p=0.000 n=10) StringFallBack/111222333444555666777888999.1234567890123456789-32 353.4n ± 26% 307.3n ± 6% -13.04% (p=0.004 n=10) Add/1234567890123456789.1234567890123456879.Add(1111.1789)-32 384.65n ± 10% 10.87n ± 3% -97.18% (p=0.000 n=10) @@ -118,8 +118,8 @@ DivFallback/12345679012345679890123456789.1234567890123456789.Div(999999)-32 DivFallback/1234.Div(12345679012345679890123456789.1234567890123456789)-32 242.1n ± 87% 292.9n ± 4% ~ (p=0.481 n=10) Pow/1.01.Pow(10)-32 724.70n ± 31% 40.83n ± 3% -94.37% (p=0.000 n=10) Pow/1.01.Pow(100)-32 1.367µ ± 8% 1.062µ ± 7% -22.28% (p=0.000 n=10) -MarshalJSON/1234567890123456789.1234567890123456879-32 451.65n ± 6% 96.56n ± 7% -78.62% (p=0.000 n=10) -MarshalJSON/0.1234567890123456879-32 204.70n ± 7% 54.62n ± 8% -73.32% (p=0.000 n=10) +MrshalJSON/1234567890123456789.1234567890123456879-32 451.65n ± 6% 72.53n ± 12% -83.94% (p=0.000 n=10) +MarshalJSON/0.1234567890123456879-32 204.70n ± 7% 43.49n ± 7% -78.75% (p=0.000 n=10) MarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 523.6n ± 15% 358.4n ± 7% -31.55% (p=0.000 n=10) UnmarshalJSON/1234567890123456789.1234567890123456879-32 488.90n ± 10% 73.75n ± 1% -84.92% (p=0.000 n=10) UnmarshalJSON/0.1234567890123456879-32 449.70n ± 9% 40.97n ± 1% -90.89% (p=0.000 n=10) diff --git a/benchmarks/bench-ss.txt b/benchmarks/bench-ss.txt index d48f9f6..7360a52 100644 --- a/benchmarks/bench-ss.txt +++ b/benchmarks/bench-ss.txt @@ -132,6 +132,16 @@ BenchmarkString/0.1234567890123456879-32 64 BenchmarkString/0.1234567890123456879-32 6106804 182.6 ns/op 80 B/op 4 allocs/op BenchmarkString/0.1234567890123456879-32 8340056 170.9 ns/op 80 B/op 4 allocs/op BenchmarkString/0.1234567890123456879-32 7816422 144.5 ns/op 80 B/op 4 allocs/op +BenchmarkString/12345.1234567890123456789-32 4406620 262.8 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 4715979 240.2 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 5084666 232.1 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 5469702 250.0 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 5063049 242.4 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 4717598 225.0 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 4795444 241.4 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 4823866 251.8 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 5811994 236.4 ns/op 176 B/op 5 allocs/op +BenchmarkString/12345.1234567890123456789-32 4685367 242.8 ns/op 176 B/op 5 allocs/op BenchmarkStringFallBack/123456789123456789123456.1234567890123456-32 3008487 382.0 ns/op 272 B/op 5 allocs/op BenchmarkStringFallBack/123456789123456789123456.1234567890123456-32 4295414 329.6 ns/op 272 B/op 5 allocs/op BenchmarkStringFallBack/123456789123456789123456.1234567890123456-32 3388437 372.2 ns/op 272 B/op 5 allocs/op diff --git a/benchmarks/bench-udec.txt b/benchmarks/bench-udec.txt index a88d3b6..847e453 100644 --- a/benchmarks/bench-udec.txt +++ b/benchmarks/bench-udec.txt @@ -82,56 +82,66 @@ BenchmarkParseFallBack/111222333444555666777888999.1234567890123456789-32 32 BenchmarkParseFallBack/111222333444555666777888999.1234567890123456789-32 3257062 360.4 ns/op 216 B/op 6 allocs/op BenchmarkParseFallBack/111222333444555666777888999.1234567890123456789-32 3369795 340.7 ns/op 216 B/op 6 allocs/op BenchmarkParseFallBack/111222333444555666777888999.1234567890123456789-32 2250596 473.5 ns/op 216 B/op 6 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 12737889 83.53 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 14842513 97.96 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 13072195 102.5 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 17354812 106.1 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 11462758 89.46 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 13311771 85.82 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 12595425 95.49 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 14100505 79.57 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 11207002 98.70 ns/op 48 B/op 1 allocs/op -BenchmarkString/1234567890123456789.1234567890123456879-32 15327704 94.33 ns/op 48 B/op 1 allocs/op -BenchmarkString/123-32 60204913 16.90 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 66484908 17.38 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 75277249 17.42 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 69646174 16.87 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 84927018 16.08 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 70302832 16.75 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 78051450 16.15 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 77942565 15.62 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 74762031 15.53 ns/op 5 B/op 1 allocs/op -BenchmarkString/123-32 69940609 15.92 ns/op 5 B/op 1 allocs/op -BenchmarkString/123456.123456-32 29572393 37.92 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 35261773 39.11 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 30349212 35.07 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 34774262 40.92 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 30988161 39.75 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 28907924 41.31 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 30145854 40.02 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 32472250 39.06 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 31239891 41.51 ns/op 16 B/op 1 allocs/op -BenchmarkString/123456.123456-32 29283334 44.08 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 29464106 36.75 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 34175943 33.69 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 34809780 32.92 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 47355177 31.46 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 31587958 33.26 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 37153270 33.03 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 48216912 32.34 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 43967180 31.27 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 34400398 30.77 ns/op 16 B/op 1 allocs/op -BenchmarkString/1234567890-32 36091290 37.88 ns/op 16 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 19779745 58.90 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 21157779 55.26 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 19251331 56.31 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 21490368 56.22 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 23569504 53.98 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 21964359 51.17 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 23290514 52.17 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 29667698 49.24 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 23520198 53.27 ns/op 24 B/op 1 allocs/op -BenchmarkString/0.1234567890123456879-32 20122322 55.45 ns/op 24 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 17156103 85.32 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 13591138 82.54 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 16135483 81.16 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 14577884 76.50 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 16238364 78.21 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 13756549 74.61 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 15475362 68.00 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 16042737 79.17 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 17206171 69.68 ns/op 48 B/op 1 allocs/op +BenchmarkString/1234567890123456789.1234567890123456879-32 16777660 71.18 ns/op 48 B/op 1 allocs/op +BenchmarkString/123-32 84630469 13.62 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 86023959 13.71 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 84910642 14.27 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 85309837 14.30 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 84251623 14.24 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 80855967 14.20 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 86456794 14.24 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 82865264 14.58 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 80792264 13.99 ns/op 3 B/op 1 allocs/op +BenchmarkString/123-32 85882203 13.91 ns/op 3 B/op 1 allocs/op +BenchmarkString/123456.123456-32 40298606 31.31 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 40338537 31.10 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 46255706 33.35 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 30628586 35.10 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 37358800 30.75 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 35548632 32.64 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 37219021 31.47 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 40519496 34.90 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 43512373 31.38 ns/op 16 B/op 1 allocs/op +BenchmarkString/123456.123456-32 40439346 31.50 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 39247867 30.38 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 37563669 32.26 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 39461016 31.87 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 39656467 28.04 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 41278750 29.52 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 44614928 32.31 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 41841336 28.30 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 41175183 26.91 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 41144018 30.82 ns/op 16 B/op 1 allocs/op +BenchmarkString/1234567890-32 41356752 30.87 ns/op 16 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 29706403 44.00 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 26762551 42.07 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 38054250 37.88 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 41109242 40.02 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 25633977 43.14 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 40989775 43.65 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 26885287 41.57 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 34875565 42.59 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 27291134 42.60 ns/op 24 B/op 1 allocs/op +BenchmarkString/0.1234567890123456879-32 29843028 46.05 ns/op 24 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 23921648 50.59 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 23288688 53.68 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 20786776 51.45 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 25201688 53.10 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 24015888 54.97 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 22051128 55.45 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 22590286 49.23 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 23671148 45.89 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 23708067 49.75 ns/op 32 B/op 1 allocs/op +BenchmarkString/12345.1234567890123456789-32 25248535 49.28 ns/op 32 B/op 1 allocs/op BenchmarkStringFallBack/123456789123456789123456.1234567890123456-32 5934763 280.8 ns/op 208 B/op 4 allocs/op BenchmarkStringFallBack/123456789123456789123456.1234567890123456-32 4672341 332.2 ns/op 208 B/op 4 allocs/op BenchmarkStringFallBack/123456789123456789123456.1234567890123456-32 4805187 300.3 ns/op 208 B/op 4 allocs/op @@ -482,66 +492,66 @@ BenchmarkPow/1.01.Pow(100)-32 BenchmarkPow/1.01.Pow(100)-32 1000000 1069 ns/op 817 B/op 13 allocs/op BenchmarkPow/1.01.Pow(100)-32 1020666 1175 ns/op 817 B/op 13 allocs/op BenchmarkPow/1.01.Pow(100)-32 1000000 1063 ns/op 817 B/op 13 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 12333306 82.35 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 15316035 92.25 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 11397050 100.9 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 15153548 98.16 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 16773282 96.11 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 14349476 95.59 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 17736074 95.20 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 11099917 98.67 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 11185342 91.44 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 10831141 98.09 ns/op 48 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 59421554 19.01 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 77643930 18.14 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 85604821 18.66 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 79088415 19.58 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 64251936 18.16 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 67508445 18.51 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 60432006 18.33 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 58575276 18.46 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 55380373 18.67 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123-32 62223451 18.20 ns/op 8 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 31232612 43.25 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 31152174 41.92 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 29544102 39.16 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 30845217 42.77 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 30356210 42.71 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 26476347 38.77 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 28465444 42.12 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 34920810 39.21 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 27043310 39.64 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/123456.123456-32 36264042 38.70 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 36310596 32.16 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 35741366 33.99 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 36492378 33.29 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 41977942 33.73 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 43512898 29.74 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 37355422 36.52 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 34457562 33.28 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 30308558 35.86 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 36823185 33.49 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/1234567890-32 35653083 35.63 ns/op 16 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 19366428 55.04 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 16934850 62.12 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 27129045 55.53 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 30341924 55.32 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 17556535 61.15 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 17381457 60.70 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 27520128 54.27 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 16953190 65.53 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 22443601 58.90 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/0.1234567890123456879-32 18845002 57.77 ns/op 24 B/op 1 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3764817 405.1 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3152901 450.9 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2663712 497.1 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2926813 520.2 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3059872 444.1 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2981570 395.2 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 4925905 435.6 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2684964 461.2 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 4464444 246.5 ns/op 384 B/op 6 allocs/op -BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 4173540 242.6 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 13965998 77.22 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 14606469 77.03 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 13927210 72.03 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 16590789 63.84 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 12796310 81.16 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 16680841 61.70 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 17385378 69.66 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 24566208 73.04 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 16322418 77.64 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890123456789.1234567890123456879-32 15287120 69.32 ns/op 48 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 72419139 16.18 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 75625140 15.64 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 66837123 16.10 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 84199441 15.03 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 71125686 14.82 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 77189959 15.66 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 72888324 15.08 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 75665901 14.56 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 80490810 15.73 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123-32 85967570 14.82 ns/op 5 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 50169931 32.54 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 40775872 31.31 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 34415953 32.58 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 33072848 34.58 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 41826874 34.16 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 33980484 35.24 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 35458191 39.90 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 39449632 35.13 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 38514502 34.05 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/123456.123456-32 35069334 34.50 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 48789456 30.33 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 45367527 27.08 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 47433658 30.71 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 58549690 29.66 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 42396516 28.70 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 41627792 29.71 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 42689048 29.72 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 40088505 26.21 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 45794577 31.50 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/1234567890-32 47742955 27.40 ns/op 16 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 23541044 46.37 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 28830591 41.27 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 30275601 43.35 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 24039360 43.57 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 39616218 43.42 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 28189186 38.14 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 25992159 44.44 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 34033808 41.04 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 25543494 46.53 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/0.1234567890123456879-32 26099420 43.56 ns/op 24 B/op 1 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2951635 391.6 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3082227 414.1 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3121087 379.6 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2888376 381.5 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2893414 387.3 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3010102 402.0 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 3164302 414.3 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2967964 402.2 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2938150 410.0 ns/op 384 B/op 6 allocs/op +BenchmarkMarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 2992862 376.1 ns/op 384 B/op 6 allocs/op BenchmarkUnmarshalJSON/1234567890123456789.1234567890123456879-32 12900291 80.62 ns/op 0 B/op 0 allocs/op BenchmarkUnmarshalJSON/1234567890123456789.1234567890123456879-32 13020310 82.50 ns/op 0 B/op 0 allocs/op BenchmarkUnmarshalJSON/1234567890123456789.1234567890123456879-32 13310517 85.78 ns/op 0 B/op 0 allocs/op diff --git a/benchmarks/benchmarks_test.go b/benchmarks/benchmarks_test.go index d909c4b..d89e3d2 100644 --- a/benchmarks/benchmarks_test.go +++ b/benchmarks/benchmarks_test.go @@ -70,6 +70,7 @@ func BenchmarkString(b *testing.B) { "123456.123456", "1234567890", "0.1234567890123456879", + "12345.1234567890123456789", } for _, tc := range testcases { diff --git a/benchmarks/benchstat.txt b/benchmarks/benchstat.txt index 7d403c0..8b22d55 100644 --- a/benchmarks/benchstat.txt +++ b/benchmarks/benchstat.txt @@ -12,11 +12,12 @@ Parse/0.1234567890123456879-32 Parse/12345678901234567890123456789.123-32 312.20n ± 8% 61.92n ± 4% -80.17% (p=0.000 n=10) ParseFallBack/123456789123456789123456.1234567890123456-32 373.2n ± 13% 477.1n ± 6% +27.83% (p=0.000 n=10) ParseFallBack/111222333444555666777888999.1234567890123456789-32 418.5n ± 5% 440.6n ± 18% ~ (p=0.353 n=10) -String/1234567890123456789.1234567890123456879-32 284.45n ± 26% 94.91n ± 12% -66.63% (p=0.000 n=10) -String/123-32 110.55n ± 7% 16.45n ± 6% -85.12% (p=0.000 n=10) -String/123456.123456-32 133.00n ± 10% 39.88n ± 5% -70.01% (p=0.000 n=10) -String/1234567890-32 145.45n ± 18% 32.98n ± 11% -77.33% (p=0.000 n=10) -String/0.1234567890123456879-32 173.80n ± 15% 54.62n ± 6% -68.57% (p=0.000 n=10) +String/1234567890123456789.1234567890123456879-32 284.45n ± 26% 77.35n ± 10% -72.81% (p=0.000 n=10) +String/123-32 110.55n ± 7% 14.22n ± 4% -87.14% (p=0.000 n=10) +String/123456.123456-32 133.00n ± 10% 31.49n ± 11% -76.33% (p=0.000 n=10) +String/1234567890-32 145.45n ± 18% 30.60n ± 8% -78.96% (p=0.000 n=10) +String/0.1234567890123456879-32 173.80n ± 15% 42.60n ± 6% -75.49% (p=0.000 n=10) +String/12345.1234567890123456789-32 241.90n ± 4% 51.02n ± 8% -78.91% (p=0.000 n=10) StringFallBack/123456789123456789123456.1234567890123456-32 394.1n ± 15% 292.6n ± 11% -25.73% (p=0.000 n=10) StringFallBack/111222333444555666777888999.1234567890123456789-32 353.4n ± 26% 298.4n ± 17% -15.56% (p=0.001 n=10) Add/1234567890123456789.1234567890123456879.Add(1111.1789)-32 384.650n ± 10% 5.348n ± 5% -98.61% (p=0.000 n=10) @@ -52,12 +53,12 @@ DivFallback/12345679012345679890123456789.1234567890123456789.Div(999999)-32 DivFallback/1234.Div(12345679012345679890123456789.1234567890123456789)-32 242.1n ± 87% 326.6n ± 11% ~ (p=0.481 n=10) Pow/1.01.Pow(10)-32 724.70n ± 31% 38.25n ± 4% -94.72% (p=0.000 n=10) Pow/1.01.Pow(100)-32 1.367µ ± 8% 1.122µ ± 5% -17.92% (p=0.000 n=10) -MarshalJSON/1234567890123456789.1234567890123456879-32 451.65n ± 6% 95.85n ± 5% -78.78% (p=0.000 n=10) -MarshalJSON/123-32 137.20n ± 12% 18.49n ± 3% -86.53% (p=0.000 n=10) -MarshalJSON/123456.123456-32 170.50n ± 10% 40.78n ± 5% -76.08% (p=0.000 n=10) -MarshalJSON/1234567890-32 189.25n ± 4% 33.61n ± 7% -82.24% (p=0.000 n=10) -MarshalJSON/0.1234567890123456879-32 204.70n ± 7% 58.34n ± 6% -71.50% (p=0.000 n=10) -MarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 523.6n ± 15% 439.9n ± 44% -15.99% (p=0.009 n=10) +MarshalJSON/1234567890123456789.1234567890123456879-32 451.65n ± 6% 72.53n ± 12% -83.94% (p=0.000 n=10) +MarshalJSON/123-32 137.20n ± 12% 15.36n ± 5% -88.80% (p=0.000 n=10) +MarshalJSON/123456.123456-32 170.50n ± 10% 34.33n ± 5% -79.87% (p=0.000 n=10) +MarshalJSON/1234567890-32 189.25n ± 4% 29.69n ± 9% -84.31% (p=0.000 n=10) +MarshalJSON/0.1234567890123456879-32 204.70n ± 7% 43.49n ± 7% -78.75% (p=0.000 n=10) +MarshalJSON/12345678901234567891234567890123456789.1234567890123456879-32 523.6n ± 15% 396.8n ± 4% -24.21% (p=0.000 n=10) UnmarshalJSON/1234567890123456789.1234567890123456879-32 488.90n ± 10% 83.82n ± 4% -82.86% (p=0.000 n=10) UnmarshalJSON/123-32 133.250n ± 9% 8.751n ± 4% -93.43% (p=0.000 n=10) UnmarshalJSON/123456.123456-32 180.60n ± 11% 23.81n ± 3% -86.81% (p=0.000 n=10) @@ -76,7 +77,7 @@ UnmarshalBinary/123456.123456-32 UnmarshalBinary/1234567890-32 65.140n ± 38% 1.790n ± 5% -97.25% (p=0.000 n=10) UnmarshalBinary/0.1234567890123456879-32 45.120n ± 18% 1.854n ± 5% -95.89% (p=0.000 n=10) UnmarshalBinary/12345678901234567891234567890123456789.1234567890123456879-32 72.44n ± 11% 75.91n ± 24% ~ (p=0.684 n=10) -geomean 183.7n 18.41n -89.98% +geomean 184.4n 18.15n -90.16% │ shopspring │ udecimal │ │ B/op │ B/op vs base │ @@ -89,10 +90,11 @@ Parse/12345678901234567890123456789.123-32 ParseFallBack/123456789123456789123456.1234567890123456-32 168.0 ± 0% 192.0 ± 0% +14.29% (p=0.000 n=10) ParseFallBack/111222333444555666777888999.1234567890123456789-32 168.0 ± 0% 216.0 ± 0% +28.57% (p=0.000 n=10) String/1234567890123456789.1234567890123456879-32 240.00 ± 0% 48.00 ± 0% -80.00% (p=0.000 n=10) -String/123-32 48.000 ± 0% 5.000 ± 0% -89.58% (p=0.000 n=10) +String/123-32 48.000 ± 0% 3.000 ± 0% -93.75% (p=0.000 n=10) String/123456.123456-32 56.00 ± 0% 16.00 ± 0% -71.43% (p=0.000 n=10) String/1234567890-32 72.00 ± 0% 16.00 ± 0% -77.78% (p=0.000 n=10) String/0.1234567890123456879-32 80.00 ± 0% 24.00 ± 0% -70.00% (p=0.000 n=10) +String/12345.1234567890123456789-32 176.00 ± 0% 32.00 ± 0% -81.82% (p=0.000 n=10) StringFallBack/123456789123456789123456.1234567890123456-32 272.0 ± 0% 208.0 ± 0% -23.53% (p=0.000 n=10) StringFallBack/111222333444555666777888999.1234567890123456789-32 272.0 ± 0% 208.0 ± 0% -23.53% (p=0.000 n=10) Add/1234567890123456789.1234567890123456879.Add(1111.1789)-32 288.0 ± 0% 0.0 ± 0% -100.00% (p=0.000 n=10) @@ -129,7 +131,7 @@ DivFallback/1234.Div(12345679012345679890123456789.1234567890123456789)-32 Pow/1.01.Pow(10)-32 576.0 ± 0% 0.0 ± 0% -100.00% (p=0.000 n=10) Pow/1.01.Pow(100)-32 1072.0 ± 0% 817.0 ± 0% -23.79% (p=0.000 n=10) MarshalJSON/1234567890123456789.1234567890123456879-32 336.00 ± 0% 48.00 ± 0% -85.71% (p=0.000 n=10) -MarshalJSON/123-32 56.000 ± 0% 8.000 ± 0% -85.71% (p=0.000 n=10) +MarshalJSON/123-32 56.000 ± 0% 5.000 ± 0% -91.07% (p=0.000 n=10) MarshalJSON/123456.123456-32 72.00 ± 0% 16.00 ± 0% -77.78% (p=0.000 n=10) MarshalJSON/1234567890-32 88.00 ± 0% 16.00 ± 0% -81.82% (p=0.000 n=10) MarshalJSON/0.1234567890123456879-32 104.00 ± 0% 24.00 ± 0% -76.92% (p=0.000 n=10) @@ -152,7 +154,7 @@ UnmarshalBinary/123456.123456-32 UnmarshalBinary/1234567890-32 40.00 ± 0% 0.00 ± 0% -100.00% (p=0.000 n=10) UnmarshalBinary/0.1234567890123456879-32 40.00 ± 0% 0.00 ± 0% -100.00% (p=0.000 n=10) UnmarshalBinary/12345678901234567891234567890123456789.1234567890123456879-32 96.00 ± 0% 96.00 ± 0% ~ (p=1.000 n=10) ¹ -geomean 122.8 ? ² ³ +geomean 123.4 ? ² ³ ¹ all samples are equal ² summaries must be >0 to compute geomean ³ ratios must be >0 to compute geomean @@ -172,6 +174,7 @@ String/123-32 String/123456.123456-32 4.000 ± 0% 1.000 ± 0% -75.00% (p=0.000 n=10) String/1234567890-32 4.000 ± 0% 1.000 ± 0% -75.00% (p=0.000 n=10) String/0.1234567890123456879-32 4.000 ± 0% 1.000 ± 0% -75.00% (p=0.000 n=10) +String/12345.1234567890123456789-32 5.000 ± 0% 1.000 ± 0% -80.00% (p=0.000 n=10) StringFallBack/123456789123456789123456.1234567890123456-32 5.000 ± 0% 4.000 ± 0% -20.00% (p=0.000 n=10) StringFallBack/111222333444555666777888999.1234567890123456789-32 5.000 ± 0% 4.000 ± 0% -20.00% (p=0.000 n=10) Add/1234567890123456789.1234567890123456879.Add(1111.1789)-32 8.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) @@ -231,7 +234,7 @@ UnmarshalBinary/123456.123456-32 UnmarshalBinary/1234567890-32 2.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) UnmarshalBinary/0.1234567890123456879-32 2.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) UnmarshalBinary/12345678901234567891234567890123456789.1234567890123456879-32 2.000 ± 0% 2.000 ± 0% ~ (p=1.000 n=10) ¹ -geomean 4.322 ? ² ³ +geomean 4.331 ? ² ³ ¹ all samples are equal ² summaries must be >0 to compute geomean ³ ratios must be >0 to compute geomean diff --git a/codec.go b/codec.go index 5f3c94e..e181c70 100644 --- a/codec.go +++ b/codec.go @@ -94,65 +94,71 @@ func (d Decimal) stringBigInt(trimTrailingZeros bool) string { return number } -var ( - // maxByteMap is a map of maximum byte needed to represent an u128 number, indexed by the number of bits. - maxByteMap = [129]byte{ - 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, // 0-9 bits - 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, // 10-19 bits - 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, // 20-29 bits - 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, // 30-39 bits - 13, 13, 13, 13, 14, 14, 14, 15, 15, 15, // 40-49 bits - 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, // 50-59 bits - 19, 19, 19, 19, 20, 20, 20, 21, 21, 21, // 60-69 bits - 22, 22, 22, 22, 23, 23, 23, 24, 24, 24, // 70-79 bits - 25, 25, 25, 25, 26, 26, 26, 27, 27, 27, // 80-89 bits - 28, 28, 28, 28, 29, 29, 29, 30, 30, 30, // 90-99 bits - 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, // 100-109 bits - 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, // 110-119 bits - 37, 37, 37, 38, 38, 38, 38, 39, 39, // 120-128 bits - } -) - func (d Decimal) stringU128(trimTrailingZeros bool, withQuote bool) string { - return unsafeBytesToString(d.bytesU128(trimTrailingZeros, withQuote)) -} - -// bytesU128 returns the byte representation of the decimal if the coefficient is u128. -func (d Decimal) bytesU128(trimTrailingZeros bool, withQuote bool) []byte { - var totalLen uint8 - byteLen := maxByteMap[d.coef.u128.bitLen()] - - // if d.prec > byteLen, that means we need to allocate upto d.prec to cover all the zeros of the fraction part - // e.g. 0.00000123, prec = 8, byteLen = 3 --> we need to allocate 8 bytes for the fraction part - if byteLen <= d.prec { - byteLen = d.prec + 1 // 1 for zero in the whole part - } - - totalLen = byteLen + 2 + // Some important notes: + // 1. If the size of buffer is already known at compile time, the compiler can allocate it on the stack (if it's small enough) + // and it will only be moved to the heap when string() is called. + // 2. When calling string(), the actual number of bytes used will be calculated. So we can safely use a large buffer + // without worrying it will affect the memory usage. It will be optimized anyway. + // 3. The actual bytes allocated is somehow weird, for example: + // - make([]byte,5) --> allocate 5 bytes + // - make([]byte,6) --> allocate 8 bytes + // - make([]byte,17) --> allocate 24 bytes + // - make([]byte,33) --> allocate 48 bytes + // So, trying to optimize the total bytes allocated by pre-defining the capacity is not worth it + // cuz the compiler optimizes it differently. My assumption is 16-byte alignment optimization in the compiler. + // However, I haven't found where this behavior is documented, just discovered it by testing. + + buf := make([]byte, 43) // 43 bytes = max(u128) + 2 (for quotes) + 1 (for sign) + 1 (for dot) if withQuote { // if withQuote is true, we need to add quotes at the beginning and the end - totalLen += 2 - buf := make([]byte, totalLen) - n := d.fillBuffer(buf[1:len(buf)-1], trimTrailingZeros) - - n += 2 // 1 for quote offset at buf[l-1], 1 for moving the index to next position - l := len(buf) - buf[l-1], buf[l-n] = '"', '"' - return buf[l-n:] + n := d.fillBuffer(buf[:len(buf)-1], trimTrailingZeros) + buf[len(buf)-1] = '"' + buf[n] = '"' + return string(buf[n:]) } - buf := make([]byte, totalLen) n := d.fillBuffer(buf, trimTrailingZeros) - - return buf[len(buf)-n:] + return string(buf[n+1:]) } +var ( + // lookup table for 00 -> 99 + table = [200]byte{ + 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, + 0x30, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31, + 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, 0x31, 0x36, 0x31, 0x37, + 0x31, 0x38, 0x31, 0x39, 0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, + 0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, 0x32, 0x38, 0x32, 0x39, + 0x33, 0x30, 0x33, 0x31, 0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, + 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, 0x34, 0x30, 0x34, 0x31, + 0x34, 0x32, 0x34, 0x33, 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, + 0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, 0x35, 0x32, 0x35, 0x33, + 0x35, 0x34, 0x35, 0x35, 0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39, + 0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, 0x36, 0x34, 0x36, 0x35, + 0x36, 0x36, 0x36, 0x37, 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, + 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 0x37, 0x36, 0x37, 0x37, + 0x37, 0x38, 0x37, 0x39, 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, + 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, 0x38, 0x38, 0x38, 0x39, + 0x39, 0x30, 0x39, 0x31, 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, + 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39, + } +) + func (d Decimal) fillBuffer(buf []byte, trimTrailingZeros bool) int { - quo, rem := d.coef.u128.QuoRem64(pow10[d.prec].lo) // max prec is 19, so we can safely use QuoRem64 + var ( + quo u128 + rem uint64 + ) + + if d.prec == 0 { + quo = d.coef.u128 + } else { + quo, rem = d.coef.u128.QuoRem64(pow10[d.prec].lo) // max prec is 19, so we can safely use QuoRem64 + } prec := d.prec - l := len(buf) - n := 0 + n := len(buf) - 1 if rem != 0 { if trimTrailingZeros { @@ -163,42 +169,62 @@ func (d Decimal) fillBuffer(buf []byte, trimTrailingZeros bool) int { prec -= zeros } - for ; rem != 0; rem /= 10 { - n++ + // fill fractional part + for rem >= 100 { + r := rem % 100 * 2 + rem /= 100 + buf[n] = table[r+1] + buf[n-1] = table[r] + n -= 2 + } - buf[l-n] = byte(rem%10) + '0' + if rem >= 10 { + r := rem * 2 + buf[n] = table[r+1] + buf[n-1] = table[r] + n -= 2 + } else { + buf[n] = byte(rem) + '0' + n-- } // fill remaining zeros - for i := n + 1; i <= int(prec); i++ { - buf[l-i] = '0' + for i := n; i > len(buf)-1-int(prec); i-- { + buf[i] = '0' } - buf[l-1-int(prec)] = '.' - n = int(prec + 1) + buf[len(buf)-int(prec)-1] = '.' + n = len(buf) - int(prec) - 2 } if quo.IsZero() { // quo is zero, we need to print at least one zero - n++ - buf[l-n] = '0' + buf[n] = '0' + n-- } else { - for { - q, r := quoRem64(quo, 10) - n++ + for quo.Cmp64(100) >= 0 { + q, r := quoRem64(quo, 100) + r = r * 2 + quo = q - buf[l-n] = byte(r%10) + '0' - if q.IsZero() { - break - } + buf[n] = table[r+1] + buf[n-1] = table[r] + n -= 2 + } - quo = q + if quo.Cmp64(10) >= 0 { + buf[n] = table[quo.lo*2+1] + buf[n-1] = table[quo.lo*2] + n -= 2 + } else { + buf[n] = byte(quo.lo) + '0' + n-- } } if d.neg { - n++ - buf[l-n] = '-' + buf[n] = '-' + n-- } return n @@ -212,9 +238,9 @@ func quoRem64(u u128, v uint64) (q u128, r uint64) { return u.QuoRem64(v) } -func unsafeBytesToString(b []byte) string { - return unsafe.String(unsafe.SliceData(b), len(b)) -} +// func unsafeBytesToString(b []byte) string { +// return unsafe.String(unsafe.SliceData(b), len(b)) +// } func unsafeStringToBytes(s string) []byte { return unsafe.Slice(unsafe.StringData(s), len(s)) @@ -223,7 +249,7 @@ func unsafeStringToBytes(s string) []byte { // MarshalJSON implements the [json.Marshaler] interface. func (d Decimal) MarshalJSON() ([]byte, error) { if !d.coef.overflow() { - return d.bytesU128(true, true), nil + return unsafeStringToBytes(d.stringU128(true, true)), nil } return []byte(`"` + d.stringBigInt(true) + `"`), nil @@ -251,7 +277,7 @@ func (d *Decimal) UnmarshalJSON(data []byte) error { func (d Decimal) MarshalText() ([]byte, error) { if !d.coef.overflow() { // Return without quotes. - return d.bytesU128(true, false), nil + return unsafeStringToBytes(d.stringU128(true, false)), nil } return []byte(d.stringBigInt(true)), nil @@ -400,7 +426,7 @@ func (d *Decimal) Scan(src any) error { var err error switch v := src.(type) { case []byte: - *d, err = Parse(unsafeBytesToString(v)) + *d, err = parseBytes(v) case string: *d, err = Parse(v) case uint64: diff --git a/codec_test.go b/codec_test.go index 39d5a10..b8504f3 100644 --- a/codec_test.go +++ b/codec_test.go @@ -139,6 +139,8 @@ func TestMarshalJSON(t *testing.T) { b, err := json.Marshal(a) require.NoError(t, err) + require.Equal(t, fmt.Sprintf(`{"a":"%s"}`, tc.in), string(b)) + // unmarshal back var c A require.NoError(t, json.Unmarshal(b, &c)) @@ -384,8 +386,7 @@ func BenchmarkUnmarshalJSON(b *testing.B) { func BenchmarkString(b *testing.B) { b.StopTimer() - a := MustParse("0.1234567890123456789") - + a := MustParse("123456.123456") b.StartTimer() for i := 0; i < b.N; i++ { _ = a.String() diff --git a/u128.go b/u128.go index 7d035ab..c90ca71 100644 --- a/u128.go +++ b/u128.go @@ -19,15 +19,6 @@ type u128 struct { lo uint64 } -// bitLen returns the number of bits required to represent u -func (u u128) bitLen() int { - if u.hi != 0 { - return bits.Len64(u.hi) + 64 - } - - return bits.Len64(u.lo) -} - // IsZero returns true if u is zero func (u u128) IsZero() bool { return u == u128{}