github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/internal/native/sse/fastfloat_test.go (about)

     1  // +build amd64 
     2  
     3  
     4  // Code generated by Makefile, DO NOT EDIT.
     5  
     6  // Code generated by Makefile, DO NOT EDIT.
     7  
     8  /*
     9   * Copyright 2021 ByteDance Inc.
    10   *
    11   * Licensed under the Apache License, Version 2.0 (the "License");
    12   * you may not use this file except in compliance with the License.
    13   * You may obtain a copy of the License at
    14   *
    15   *     http://www.apache.org/licenses/LICENSE-2.0
    16   *
    17   * Unless required by applicable law or agreed to in writing, software
    18   * distributed under the License is distributed on an "AS IS" BASIS,
    19   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    20   * See the License for the specific language governing permissions and
    21   * limitations under the License.
    22   */
    23  
    24  package sse
    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  }