浏览代码

optimize read float

Tao Wen 9 年之前
父节点
当前提交
ec19f6de6a
共有 2 个文件被更改,包括 44 次插入19 次删除
  1. 40 18
      jsoniter.go
  2. 4 1
      jsoniter_float_test.go

+ 40 - 18
jsoniter.go

@@ -133,6 +133,8 @@ func (iter *Iterator) readByte() (ret byte) {
 			ret = iter.buf[iter.head]
 			iter.head++
 			return ret
+		} else {
+			return 0
 		}
 	}
 	ret = iter.buf[iter.head]
@@ -557,16 +559,26 @@ func (iter *Iterator) readObjectField() (ret string) {
 }
 
 func (iter *Iterator) ReadFloat32() (ret float32) {
-	str := make([]byte, 0, 4)
-	for c := iter.readByte(); iter.Error == nil; c = iter.readByte() {
-		switch c {
-		case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-			str = append(str, c)
-			continue
-		default:
-			iter.unreadByte()
+	strBuf := [8]byte{}
+	str := strBuf[0:0]
+	hasMore := true
+	for(hasMore) {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+				str = append(str, c)
+				continue
+			default:
+				hasMore = false
+				break
+			}
+		}
+		if hasMore {
+			if !iter.loadMore() {
+				break
+			}
 		}
-		break
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
 		return
@@ -580,16 +592,26 @@ func (iter *Iterator) ReadFloat32() (ret float32) {
 }
 
 func (iter *Iterator) ReadFloat64() (ret float64) {
-	str := make([]byte, 0, 4)
-	for c := iter.readByte(); iter.Error == nil; c = iter.readByte() {
-		switch c {
-		case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-			str = append(str, c)
-			continue
-		default:
-			iter.unreadByte()
+	strBuf := [8]byte{}
+	str := strBuf[0:0]
+	hasMore := true
+	for(hasMore) {
+		for i := iter.head; i < iter.tail; i++ {
+			c := iter.buf[i]
+			switch c {
+			case '-', '+', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+				str = append(str, c)
+				continue
+			default:
+				hasMore = false
+				break
+			}
+		}
+		if hasMore {
+			if !iter.loadMore() {
+				break
+			}
 		}
-		break
 	}
 	if iter.Error != nil && iter.Error != io.EOF {
 		return

+ 4 - 1
jsoniter_float_test.go

@@ -3,6 +3,7 @@ package jsoniter
 import (
 	"testing"
 	"encoding/json"
+	"fmt"
 )
 
 func Test_float64_0(t *testing.T) {
@@ -25,13 +26,15 @@ func Test_float32_1_dot_1_comma(t *testing.T) {
 	iter := ParseString(`1.1,`)
 	val := iter.ReadFloat32()
 	if val != 1.1 {
+		fmt.Println(iter.Error)
 		t.Fatal(val)
 	}
 }
 
 func Benchmark_jsoniter_float(b *testing.B) {
+	b.ReportAllocs()
 	for n := 0; n < b.N; n++ {
-		iter := ParseString(`1.1`)
+		iter := ParseString(`1.1111111111`)
 		iter.ReadFloat64()
 	}
 }