1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-01 21:24:21 +02:00

optimize read float

This commit is contained in:
Tao Wen 2016-12-06 10:21:47 +08:00
parent 3e160d6f5d
commit 688f2968dd
2 changed files with 31 additions and 30 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"unicode/utf16" "unicode/utf16"
"strconv" "strconv"
"unsafe"
) )
type Iterator struct { type Iterator struct {
@ -519,57 +520,49 @@ func (iter *Iterator) readObjectField() (ret string) {
} }
func (iter *Iterator) ReadFloat32() (ret float32) { func (iter *Iterator) ReadFloat32() (ret float32) {
str := make([]byte, 0, 10) str := make([]byte, 0, 4)
for c := iter.readByte(); iter.Error == nil; c = iter.readByte() { for c := iter.readByte(); iter.Error == nil; c = iter.readByte() {
switch c { switch c {
case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
str = append(str, c) str = append(str, c)
continue
default: default:
iter.unreadByte() iter.unreadByte()
val, err := strconv.ParseFloat(string(str), 32) }
break
}
if iter.Error != nil && iter.Error != io.EOF {
return
}
val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 32)
if err != nil { if err != nil {
iter.Error = err iter.Error = err
return return
} }
return float32(val) return float32(val)
}
}
if iter.Error == io.EOF {
val, err := strconv.ParseFloat(string(str), 32)
if err != nil {
iter.Error = err
return
}
return float32(val)
}
return
} }
func (iter *Iterator) ReadFloat64() (ret float64) { func (iter *Iterator) ReadFloat64() (ret float64) {
str := make([]byte, 0, 10) str := make([]byte, 0, 4)
for c := iter.readByte(); iter.Error == nil; c = iter.readByte() { for c := iter.readByte(); iter.Error == nil; c = iter.readByte() {
switch c { switch c {
case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
str = append(str, c) str = append(str, c)
continue
default: default:
iter.unreadByte() iter.unreadByte()
val, err := strconv.ParseFloat(string(str), 64) }
break
}
if iter.Error != nil && iter.Error != io.EOF {
return
}
val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 64)
if err != nil { if err != nil {
iter.Error = err iter.Error = err
return return
} }
return val return val
}
}
if iter.Error == io.EOF {
val, err := strconv.ParseFloat(string(str), 64)
if err != nil {
iter.Error = err
return
}
return val
}
return
} }
func (iter *Iterator) ReadBool() (ret bool) { func (iter *Iterator) ReadBool() (ret bool) {

View File

@ -21,6 +21,14 @@ func Test_float64_1_dot_1(t *testing.T) {
} }
} }
func Test_float32_1_dot_1_comma(t *testing.T) {
iter := ParseString(`1.1,`)
val := iter.ReadFloat32()
if val != 1.1 {
t.Fatal(val)
}
}
func Benchmark_jsoniter_float(b *testing.B) { func Benchmark_jsoniter_float(b *testing.B) {
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
iter := ParseString(`1.1`) iter := ParseString(`1.1`)