1
2
3
4
5
6
7
8
23
24 package avx2
25
26 import (
27 `encoding/json`
28 `math`
29 `math/rand`
30 `strconv`
31 `testing`
32
33 `github.com/stretchr/testify/assert`
34 )
35
36 func TestFastFloat_Encode(t *testing.T) {
37 var buf [64]byte
38 assert.Equal(t, "0" , string(buf[:f64toa(&buf[0], 0)]))
39 assert.Equal(t, "-0" , string(buf[:f64toa(&buf[0], math.Float64frombits(0x8000000000000000))]))
40 assert.Equal(t, "12340000000" , string(buf[:f64toa(&buf[0], 1234e7)]))
41 assert.Equal(t, "12.34" , string(buf[:f64toa(&buf[0], 1234e-2)]))
42 assert.Equal(t, "0.001234" , string(buf[:f64toa(&buf[0], 1234e-6)]))
43 assert.Equal(t, "1e+30" , string(buf[:f64toa(&buf[0], 1e30)]))
44 assert.Equal(t, "1.234e+33" , string(buf[:f64toa(&buf[0], 1234e30)]))
45 assert.Equal(t, "1.234e+308" , string(buf[:f64toa(&buf[0], 1234e305)]))
46 assert.Equal(t, "1.234e-317" , string(buf[:f64toa(&buf[0], 1234e-320)]))
47 assert.Equal(t, "1.7976931348623157e+308" , string(buf[:f64toa(&buf[0], 1.7976931348623157e308)]))
48 assert.Equal(t, "-12340000000" , string(buf[:f64toa(&buf[0], -1234e7)]))
49 assert.Equal(t, "-12.34" , string(buf[:f64toa(&buf[0], -1234e-2)]))
50 assert.Equal(t, "-0.001234" , string(buf[:f64toa(&buf[0], -1234e-6)]))
51 assert.Equal(t, "-1e+30" , string(buf[:f64toa(&buf[0], -1e30)]))
52 assert.Equal(t, "-1.234e+33" , string(buf[:f64toa(&buf[0], -1234e30)]))
53 assert.Equal(t, "-1.234e+308" , string(buf[:f64toa(&buf[0], -1234e305)]))
54 assert.Equal(t, "-1.234e-317" , string(buf[:f64toa(&buf[0], -1234e-320)]))
55 assert.Equal(t, "-2.2250738585072014e-308" , string(buf[:f64toa(&buf[0], -2.2250738585072014e-308)]))
56 }
57
58 func TestFastFloat_Random(t *testing.T) {
59 var buf [64]byte
60 N := 10000
61 for i := 0; i < N; i++ {
62 b64 := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
63 f64 := math.Float64frombits(b64)
64
65 jout, jerr := json.Marshal(f64)
66 n := f64toa(&buf[0], f64)
67 if jerr == nil {
68 assert.Equal(t, jout, buf[:n])
69 } else {
70 assert.True(t, n == 0)
71 }
72
73 f32 := math.Float32frombits(rand.Uint32())
74 jout, jerr = json.Marshal(f32)
75 n = f32toa(&buf[0], f32)
76 if jerr == nil {
77 assert.Equal(t, jout, buf[:n])
78 } else {
79 assert.True(t, n == 0)
80 }
81 }
82 }
83
84 func BenchmarkParseFloat64(b *testing.B) {
85 var f64toaBenches = []struct {
86 name string
87 float float64
88 }{
89 {"Zero", 0},
90 {"Decimal", 33909},
91 {"Float", 339.7784},
92 {"Exp", -5.09e75},
93 {"NegExp", -5.11e-95},
94 {"LongExp", 1.234567890123456e-78},
95 {"Big", 123456789123456789123456789},
96
97 }
98 for _, c := range f64toaBenches {
99 f64bench := []struct {
100 name string
101 test func(*testing.B)
102 }{{
103 name: "StdLib",
104 test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:0], c.float, 'g', -1, 64) }},
105 }, {
106 name: "FastFloat",
107 test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { f64toa(&buf[0], c.float) }},
108 }}
109 for _, bm := range f64bench {
110 name := bm.name + "_" + c.name
111 b.Run(name, bm.test)
112 }
113 }
114 }
115
116 func BenchmarkParseFloat32(b *testing.B) {
117 var f32toaBenches = []struct {
118 name string
119 float float32
120 }{
121 {"Zero", 0},
122 {"Integer", 33909},
123 {"ExactFraction", 3.375},
124 {"Point", 339.7784},
125 {"Exp", -5.09e25},
126 {"NegExp", -5.11e-25},
127 {"Shortest", 1.234567e-8},
128 }
129 for _, c := range f32toaBenches {
130 bench := []struct {
131 name string
132 test func(*testing.B)
133 }{{
134 name: "StdLib32",
135 test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:0], float64(c.float), 'g', -1, 32) }},
136 }, {
137 name: "FastFloat32",
138 test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { f32toa(&buf[0], c.float) }},
139 }}
140 for _, bm := range bench {
141 name := bm.name + "_" + c.name
142 b.Run(name, bm.test)
143 }
144 }
145 }
146
View as plain text