mirror of
https://github.com/ii64/sonic.git
synced 2026-06-21 00:46:43 +08:00
Compare commits
3 commits
2138136685
...
56e81a633e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56e81a633e | ||
|
|
5e54c02172 | ||
|
|
ccc0f3f1e3 |
75 changed files with 15021 additions and 9607 deletions
5
.github/workflows/benchmark-linux-amd64.yml
vendored
5
.github/workflows/benchmark-linux-amd64.yml
vendored
|
|
@ -23,8 +23,11 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Benchmark
|
||||
- name: Benchmark sonic
|
||||
run: sh bench.sh
|
||||
|
||||
# - name: Benchmark third-party
|
||||
# run: go test -benchmem -run=^$ -bench . -v ./generic_test
|
||||
|
||||
# - name: Diff
|
||||
# run: ./bench.py -b '"^Benchmark.*Sonic"' -c
|
||||
|
|
|
|||
7
.github/workflows/push-check-go118.yml
vendored
7
.github/workflows/push-check-go118.yml
vendored
|
|
@ -21,10 +21,9 @@ jobs:
|
|||
${{ runner.os }}-go-
|
||||
|
||||
- name: Unit Test
|
||||
run: GOMAXPROCS=4 go test -v -gcflags=-d=checkptr=0 -race ./...
|
||||
run: |
|
||||
GOMAXPROCS=4 go test -v -gcflags=-d=checkptr=0 -race ./...
|
||||
GOMAXPROCS=4 go test -v -gcflags=-d=checkptr=0 -race ./external_jsonlib_test/...
|
||||
|
||||
- name: Generic Test
|
||||
run: GOMAXPROCS=4 go test -v -gcflags=-d=checkptr=0 -race ./generic_test
|
||||
|
||||
- name: Benchmark
|
||||
run: go test -benchmem -run=^$ -bench . -v ./generic_test
|
||||
5
.github/workflows/push-check-linux-amd64.yml
vendored
5
.github/workflows/push-check-linux-amd64.yml
vendored
|
|
@ -24,4 +24,7 @@ jobs:
|
|||
${{ runner.os }}-go-
|
||||
|
||||
- name: Unit Test
|
||||
run: go test -v -gcflags=-d=checkptr=0 ./...
|
||||
run: |
|
||||
go test -v -gcflags=-d=checkptr=0 ./...
|
||||
cd ./external_jsonlib_test
|
||||
go test -v -gcflags=-d=checkptr=0 ./...
|
||||
|
|
|
|||
17
Makefile
17
Makefile
|
|
@ -14,22 +14,22 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
ARCH := avx avx2 sse4
|
||||
ARCH := avx avx2 sse
|
||||
TMP_DIR := output
|
||||
OUT_DIR := internal/native
|
||||
SRC_FILE := native/native.c
|
||||
|
||||
CPU_avx := amd64
|
||||
CPU_avx2 := amd64
|
||||
CPU_sse4 := amd64
|
||||
CPU_sse := amd64
|
||||
|
||||
TMPL_avx := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64
|
||||
TMPL_avx2 := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64
|
||||
TMPL_sse4 := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64
|
||||
TMPL_sse := fastint_amd64_test fastfloat_amd64_test native_amd64_test native_export_amd64
|
||||
|
||||
CFLAGS_avx := -msse4 -mavx -mno-avx2 -DUSE_AVX=1 -DUSE_AVX2=0
|
||||
CFLAGS_avx2 := -msse4 -mavx -mavx2 -DUSE_AVX=1 -DUSE_AVX2=1
|
||||
CFLAGS_sse4 := -msse4 -mno-avx -mno-avx2
|
||||
CFLAGS_avx := -msse -mno-sse4 -mavx -mno-avx2 -DUSE_AVX=1 -DUSE_AVX2=0
|
||||
CFLAGS_avx2 := -msse -mno-sse4 -mavx -mavx2 -DUSE_AVX=1 -DUSE_AVX2=1
|
||||
CFLAGS_sse := -msse -mno-sse4 -mno-avx -mno-avx2
|
||||
|
||||
CC_amd64 := clang
|
||||
ASM2ASM_amd64 := tools/asm2asm/asm2asm.py
|
||||
|
|
@ -43,6 +43,7 @@ CFLAGS += -fno-rtti
|
|||
CFLAGS += -fno-stack-protector
|
||||
CFLAGS += -nostdlib
|
||||
CFLAGS += -O3
|
||||
CFLAGS += -Wall -Werror
|
||||
|
||||
NATIVE_SRC := $(wildcard native/*.h)
|
||||
NATIVE_SRC += $(wildcard native/*.c)
|
||||
|
|
@ -99,8 +100,8 @@ endef
|
|||
all: ${ARCH}
|
||||
|
||||
clean:
|
||||
rm -vfr ${TMP_DIR}/{sse4,avx,avx2}
|
||||
rm -vfr ${OUT_DIR}/{sse4,avx,avx2}
|
||||
rm -vfr ${TMP_DIR}/{sse,avx,avx2}
|
||||
rm -vfr ${OUT_DIR}/{sse,avx,avx2}
|
||||
|
||||
$(foreach \
|
||||
arch, \
|
||||
|
|
|
|||
|
|
@ -17,17 +17,15 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`os`
|
||||
`encoding/json`
|
||||
`testing`
|
||||
`time`
|
||||
`os`
|
||||
`runtime`
|
||||
`runtime/debug`
|
||||
`sync`
|
||||
`testing`
|
||||
`time`
|
||||
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/assert`
|
||||
`github.com/tidwall/gjson`
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -257,39 +255,6 @@ func BenchmarkParser_Sonic(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkParser_Gjson(b *testing.B) {
|
||||
gjson.Parse(_TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
_ = value.Value()
|
||||
return true
|
||||
})
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
gjson.Parse(_TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
_ = value.Value()
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParser_Jsoniter(b *testing.B) {
|
||||
v := jsoniter.Get([]byte(_TwitterJson)).GetInterface()
|
||||
if v == nil {
|
||||
b.Fatal(v)
|
||||
}
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = jsoniter.Get([]byte(_TwitterJson)).GetInterface()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParser_Parallel_Sonic(b *testing.B) {
|
||||
r, _ := NewParser(_TwitterJson).Parse()
|
||||
if err := r.LoadAll(); err != nil {
|
||||
|
|
@ -305,40 +270,6 @@ func BenchmarkParser_Parallel_Sonic(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkParser_Parallel_Gjson(b *testing.B) {
|
||||
gjson.Parse(_TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
return true
|
||||
})
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
gjson.Parse(_TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
_ = value.Value()
|
||||
return true
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParser_Parallel_Jsoniter(b *testing.B) {
|
||||
var bv = []byte(_TwitterJson)
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var out interface{}
|
||||
_ = jsoniter.Unmarshal(bv, &out)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Sonic(b *testing.B) {
|
||||
ast, _ := NewParser(_TwitterJson).Parse()
|
||||
node, _ := ast.Get("statuses").Index(2).Get("id").Int64()
|
||||
|
|
@ -353,37 +284,6 @@ func BenchmarkParseOne_Sonic(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Gjson(b *testing.B) {
|
||||
ast := gjson.Parse(_TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
v := node.Int()
|
||||
if v != 249289491129438208 {
|
||||
b.Fatal(node)
|
||||
}
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := gjson.Parse(_TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
_ = node.Int()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Jsoniter(b *testing.B) {
|
||||
data := []byte(_TwitterJson)
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249289491129438208 {
|
||||
b.Fail()
|
||||
}
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
_ = ast.ToInt()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Parallel_Sonic(b *testing.B) {
|
||||
ast, _ := NewParser(_TwitterJson).Parse()
|
||||
node, _ := ast.Get("statuses").Index(2).Get("id").Int64()
|
||||
|
|
@ -400,42 +300,6 @@ func BenchmarkParseOne_Parallel_Sonic(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Parallel_Gjson(b *testing.B) {
|
||||
ast := gjson.Parse(_TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
v := node.Int()
|
||||
if v != 249289491129438208 {
|
||||
b.Fatal(node)
|
||||
}
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := gjson.Parse(_TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
_ = node.Int()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Parallel_Jsoniter(b *testing.B) {
|
||||
data := []byte(_TwitterJson)
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249289491129438208 {
|
||||
b.Fail()
|
||||
}
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
data := []byte(_TwitterJson)
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
_ = ast.ToInt()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Sonic(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
|
|
@ -454,43 +318,6 @@ func BenchmarkParseSeven_Sonic(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := gjson.Parse(_TwitterJson)
|
||||
node := ast.Get("statuses.3.id")
|
||||
node = ast.Get( "statuses.3.user.entities.description")
|
||||
node = ast.Get( "statuses.3.user.entities.url.urls")
|
||||
node = ast.Get( "statuses.3.user.entities.url")
|
||||
node = ast.Get( "statuses.3.user.created_at")
|
||||
node = ast.Get( "statuses.3.user.name")
|
||||
node = ast.Get( "statuses.3.text")
|
||||
if node.Value() == nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
data := []byte(_TwitterJson)
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := jsoniter.Get(data)
|
||||
node := ast.Get("statuses", 3, "id")
|
||||
node = ast.Get("statuses", 3, "user", "entities","description")
|
||||
node = ast.Get("statuses", 3, "user", "entities","url","urls")
|
||||
node = ast.Get("statuses", 3, "user", "entities","url")
|
||||
node = ast.Get("statuses", 3, "user", "created_at")
|
||||
node = ast.Get("statuses", 3, "user", "name")
|
||||
node = ast.Get("statuses", 3, "text")
|
||||
if node.LastError() != nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Parallel_Sonic(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
|
|
@ -510,44 +337,3 @@ func BenchmarkParseSeven_Parallel_Sonic(b *testing.B) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Parallel_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := gjson.Parse(_TwitterJson)
|
||||
node := ast.Get("statuses.3.id")
|
||||
node = ast.Get( "statuses.3.user.entities.description")
|
||||
node = ast.Get( "statuses.3.user.entities.url.urls")
|
||||
node = ast.Get( "statuses.3.user.entities.url")
|
||||
node = ast.Get( "statuses.3.user.created_at")
|
||||
node = ast.Get( "statuses.3.user.name")
|
||||
node = ast.Get( "statuses.3.text")
|
||||
if node.Value() == nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Parallel_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
data := []byte(_TwitterJson)
|
||||
ast := jsoniter.Get(data)
|
||||
node := ast.Get("statuses", 3, "id")
|
||||
node = ast.Get("statuses", 3, "user", "entities","description")
|
||||
node = ast.Get("statuses", 3, "user", "entities","url","urls")
|
||||
node = ast.Get("statuses", 3, "user", "entities","url")
|
||||
node = ast.Get("statuses", 3, "user", "created_at")
|
||||
node = ast.Get("statuses", 3, "user", "name")
|
||||
node = ast.Get("statuses", 3, "text")
|
||||
if node.LastError() != nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,17 +17,13 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
`testing`
|
||||
`runtime`
|
||||
`sync`
|
||||
`fmt`
|
||||
`math`
|
||||
`runtime`
|
||||
`strconv`
|
||||
`sync`
|
||||
`testing`
|
||||
|
||||
`github.com/tidwall/sjson`
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/assert`
|
||||
`github.com/tidwall/gjson`
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -192,29 +188,6 @@ func TestSearchNotExist(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := gjson.Get(_TwitterJson, "statuses.3.id")
|
||||
node := ast.Int()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
data := []byte(_TwitterJson)
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := jsoniter.Get(data, "statuses", 3, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Sonic(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
ast := NewSearcher(_TwitterJson)
|
||||
|
|
@ -230,33 +203,6 @@ func BenchmarkGetOne_Sonic(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Parallel_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := gjson.Get(_TwitterJson, "statuses.3.id")
|
||||
node := ast.Int()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Parallel_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
data := []byte(_TwitterJson)
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := jsoniter.Get(data, "statuses", 3, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Parallel_Sonic(b *testing.B) {
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
|
|
@ -293,36 +239,6 @@ func BenchmarkSetOne_Sonic(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Sjson(b *testing.B) {
|
||||
path := fmt.Sprintf("%s.%d.%s", "statuses", 3, "id")
|
||||
_, err := sjson.Set(_TwitterJson, path, math.MaxInt32)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sjson.Set(_TwitterJson, path, math.MaxInt32)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Jsoniter(b *testing.B) {
|
||||
data := []byte(_TwitterJson)
|
||||
node, ok := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
if !ok {
|
||||
b.Fatal(node)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(len(data)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
node, _ := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
node["id"] = math.MaxInt32
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Parallel_Sonic(b *testing.B) {
|
||||
node, err := NewSearcher(_TwitterJson).GetByPath("statuses", 3)
|
||||
if err != nil {
|
||||
|
|
@ -343,37 +259,3 @@ func BenchmarkSetOne_Parallel_Sonic(b *testing.B) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Parallel_Sjson(b *testing.B) {
|
||||
path := fmt.Sprintf("%s.%d.%s", "statuses", 3, "id")
|
||||
_, err := sjson.Set(_TwitterJson, path, math.MaxInt32)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(_TwitterJson)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
sjson.Set(_TwitterJson, path, math.MaxInt32)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Parallel_Jsoniter(b *testing.B) {
|
||||
data := []byte(_TwitterJson)
|
||||
node, ok := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
if !ok {
|
||||
b.Fatal(node)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(len(data)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
node, _ := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
node["id"] = math.MaxInt32
|
||||
}
|
||||
})
|
||||
}
|
||||
7
bench.sh
7
bench.sh
|
|
@ -16,5 +16,12 @@ go test -benchmem -run=^$ -benchtime=10000x -bench "^(BenchmarkParser_.*|Benchma
|
|||
|
||||
go test -benchmem -run=^$ -benchtime=10000000x -bench "^(BenchmarkNodeGetByPath|BenchmarkStructGetByPath|BenchmarkNodeIndex|BenchmarkStructIndex|BenchmarkSliceIndex|BenchmarkMapIndex|BenchmarkNodeGet|BenchmarkSliceGet|BenchmarkMapGet|BenchmarkNodeSet|BenchmarkMapSet|BenchmarkNodeSetByIndex|BenchmarkSliceSetByIndex|BenchmarkStructSetByIndex|BenchmarkNodeUnset|BenchmarkMapUnset|BenchmarkNodUnsetByIndex|BenchmarkSliceUnsetByIndex|BenchmarkNodeAdd|BenchmarkSliceAdd|BenchmarkMapAdd)$"
|
||||
|
||||
cd $pwd/external_jsonlib_test/benchmark_test
|
||||
go test -benchmem -run=^$ -benchtime=100000x -bench "^(BenchmarkEncoder_.*|BenchmarkDecoder_.*)$"
|
||||
|
||||
go test -benchmem -run=^$ -benchtime=1000000x -bench "^(BenchmarkGet.*|BenchmarkSet.*)$"
|
||||
|
||||
go test -benchmem -run=^$ -benchtime=10000x -bench "^(BenchmarkParser_.*)$"
|
||||
|
||||
unset SONIC_NO_ASYNC_GC
|
||||
cd $pwd
|
||||
|
|
@ -828,11 +828,11 @@ var unmarshalTests = []unmarshalTest{
|
|||
{in: `0.000001`, ptr: new(float64), out: 0.000001, golden: true},
|
||||
{in: `1e-7`, ptr: new(float64), out: 1e-7, golden: true},
|
||||
{in: `100000000000000000000`, ptr: new(float64), out: 100000000000000000000.0, golden: true},
|
||||
{in: `1e21`, ptr: new(float64), out: 1e21, golden: true},
|
||||
{in: `1e+21`, ptr: new(float64), out: 1e21, golden: true},
|
||||
{in: `-0.000001`, ptr: new(float64), out: -0.000001, golden: true},
|
||||
{in: `-1e-7`, ptr: new(float64), out: -1e-7, golden: true},
|
||||
{in: `-100000000000000000000`, ptr: new(float64), out: -100000000000000000000.0, golden: true},
|
||||
{in: `-1e21`, ptr: new(float64), out: -1e21, golden: true},
|
||||
{in: `-1e+21`, ptr: new(float64), out: -1e21, golden: true},
|
||||
{in: `999999999999999900000`, ptr: new(float64), out: 999999999999999900000.0, golden: true},
|
||||
{in: `9007199254740992`, ptr: new(float64), out: 9007199254740992.0, golden: true},
|
||||
{in: `9007199254740993`, ptr: new(float64), out: 9007199254740992.0, golden: false},
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ import (
|
|||
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
`github.com/davecgh/go-spew/spew`
|
||||
gojson `github.com/goccy/go-json`
|
||||
`github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/assert`
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
|
@ -328,30 +326,6 @@ func BenchmarkDecoder_Generic_StdLib(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Generic_JsonIter(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v interface{}
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Generic_GoJson(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v interface{}
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Binding_Sonic(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
_, _ = decode(TwitterJson, &w, true)
|
||||
|
|
@ -386,30 +360,6 @@ func BenchmarkDecoder_Binding_StdLib(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Binding_JsonIter(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v TwitterStruct
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Binding_GoJson(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v TwitterStruct
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Generic_Sonic(b *testing.B) {
|
||||
var w interface{}
|
||||
_, _ = decode(TwitterJson, &w, true)
|
||||
|
|
@ -450,34 +400,6 @@ func BenchmarkDecoder_Parallel_Generic_StdLib(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Generic_JsonIter(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v interface{}
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Generic_GoJson(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v interface{}
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Binding_Sonic(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
_, _ = decode(TwitterJson, &w, true)
|
||||
|
|
@ -518,34 +440,6 @@ func BenchmarkDecoder_Parallel_Binding_StdLib(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Binding_JsonIter(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v TwitterStruct
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Binding_GoJson(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v TwitterStruct
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSkip_Sonic(b *testing.B) {
|
||||
var data = rt.Str2Mem(TwitterJson)
|
||||
if ret, _ := Skip(data); ret < 0 {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import (
|
|||
`strings`
|
||||
`testing`
|
||||
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/assert`
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
|
@ -83,76 +82,6 @@ func TestDecodeEmpty(t *testing.T) {
|
|||
assert.Equal(t, v1, v2)
|
||||
}
|
||||
|
||||
func TestDecodeSingle(t *testing.T) {
|
||||
var str = _Single_JSON
|
||||
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
var r2 = strings.NewReader(str)
|
||||
var v2 map[string]interface{}
|
||||
var d2 = NewStreamDecoder(r2)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es1 := d1.Decode(&v1)
|
||||
ee1 := d2.Decode(&v2)
|
||||
assert.Equal(t, es1, ee1)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
}
|
||||
|
||||
func TestDecodeMulti(t *testing.T) {
|
||||
var str = _Triple_JSON
|
||||
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
var r2 = strings.NewReader(str)
|
||||
var v2 map[string]interface{}
|
||||
var d2 = NewStreamDecoder(r2)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es1 := d1.Decode(&v1)
|
||||
ee1 := d2.Decode(&v2)
|
||||
assert.Equal(t, es1, ee1)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es4 := d1.Decode(&v1)
|
||||
ee4 := d2.Decode(&v2)
|
||||
assert.Equal(t, es4, ee4)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es2 := d1.Decode(&v1)
|
||||
ee2 := d2.Decode(&v2)
|
||||
assert.Equal(t, es2, ee2)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
// fmt.Printf("v:%#v\n", v1)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es5 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es5)
|
||||
ee5 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee5)
|
||||
}
|
||||
|
||||
type HaltReader struct {
|
||||
halts map[int]bool
|
||||
buf string
|
||||
|
|
@ -199,49 +128,6 @@ var testHalts = func () map[int]bool {
|
|||
20: true}
|
||||
}
|
||||
|
||||
func TestDecodeHalt(t *testing.T) {
|
||||
var str = _Triple_JSON
|
||||
var r1 = NewHaltReader(str, testHalts())
|
||||
var r2 = NewHaltReader(str, testHalts())
|
||||
var v1 map[string]interface{}
|
||||
var v2 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
var d2 = NewStreamDecoder(r2)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
err1 := d1.Decode(&v1)
|
||||
err2 := d2.Decode(&v2)
|
||||
assert.Equal(t, err1, err2)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es4 := d1.Decode(&v1)
|
||||
ee4 := d2.Decode(&v2)
|
||||
assert.Equal(t, es4, ee4)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es2 := d1.Decode(&v1)
|
||||
ee2 := d2.Decode(&v2)
|
||||
assert.Equal(t, es2, ee2)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es5 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es5)
|
||||
ee5 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee5)
|
||||
}
|
||||
|
||||
func TestBuffered(t *testing.T) {
|
||||
var str = _Triple_JSON
|
||||
var r1 = NewHaltReader(str, testHalts())
|
||||
|
|
@ -274,43 +160,6 @@ func TestBuffered(t *testing.T) {
|
|||
assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
}
|
||||
|
||||
func TestMore(t *testing.T) {
|
||||
var str = _Triple_JSON
|
||||
var r2 = NewHaltReader(str, testHalts())
|
||||
var v2 map[string]interface{}
|
||||
var d2 = NewStreamDecoder(r2)
|
||||
var r1 = NewHaltReader(str, testHalts())
|
||||
var v1 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
require.Nil(t, d1.Decode(&v1))
|
||||
require.Nil(t, d2.Decode(&v2))
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es4 := d1.Decode(&v1)
|
||||
ee4 := d2.Decode(&v2)
|
||||
assert.Equal(t, es4, ee4)
|
||||
assert.Equal(t, v1, v2)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es2 := d1.Decode(&v1)
|
||||
ee2 := d2.Decode(&v2)
|
||||
assert.Equal(t, es2, ee2)
|
||||
assert.Equal(t, v1, v2)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es5 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es5)
|
||||
ee5 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee5)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
}
|
||||
|
||||
func BenchmarkDecodeStream_Std(b *testing.B) {
|
||||
b.Run("single", func (b *testing.B) {
|
||||
var str = _Single_JSON
|
||||
|
|
@ -345,40 +194,6 @@ func BenchmarkDecodeStream_Std(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecodeStream_Jsoniter(b *testing.B) {
|
||||
b.Run("single", func (b *testing.B) {
|
||||
var str = _Single_JSON
|
||||
for i:=0; i<b.N; i++ {
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
dc := jsoniter.NewDecoder(r1)
|
||||
_ = dc.Decode(&v1)
|
||||
_ = dc.Decode(&v1)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("double", func (b *testing.B) {
|
||||
var str = _Double_JSON
|
||||
for i:=0; i<b.N; i++ {
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
dc := jsoniter.NewDecoder(r1)
|
||||
_ = dc.Decode(&v1)
|
||||
_ = dc.Decode(&v1)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("halt", func (b *testing.B) {
|
||||
var str = _Double_JSON
|
||||
for i:=0; i<b.N; i++ {
|
||||
var r1 = NewHaltReader(str, testHalts())
|
||||
var v1 map[string]interface{}
|
||||
dc := jsoniter.NewDecoder(r1)
|
||||
_ = dc.Decode(&v1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// func BenchmarkDecodeError_Sonic(b *testing.B) {
|
||||
// var str = `\b测试1234`
|
||||
// for i:=0; i<b.N; i++ {
|
||||
|
|
|
|||
|
|
@ -732,6 +732,7 @@ var (
|
|||
|
||||
var (
|
||||
_F_f64toa = jit.Imm(int64(native.S_f64toa))
|
||||
_F_f32toa = jit.Imm(int64(native.S_f32toa))
|
||||
_F_i64toa = jit.Imm(int64(native.S_i64toa))
|
||||
_F_u64toa = jit.Imm(int64(native.S_u64toa))
|
||||
_F_b64encode = jit.Imm(int64(_subr__b64encode))
|
||||
|
|
@ -851,8 +852,7 @@ func (self *_Assembler) _asm_OP_f32(_ *_Instr) {
|
|||
self.save_c() // SAVE $C_regs
|
||||
self.rbuf_di() // MOVQ RP, DI
|
||||
self.Emit("MOVSS" , jit.Ptr(_SP_p, 0), _X0) // MOVSS (SP.p), X0
|
||||
self.Emit("CVTSS2SD", _X0, _X0) // CVTSS2SD X0, X0
|
||||
self.call_c(_F_f64toa) // CALL_C f64toa
|
||||
self.call_c(_F_f32toa) // CALL_C f64toa
|
||||
self.Emit("ADDQ" , _AX, _RL) // ADDQ AX, RL
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -745,6 +745,7 @@ var (
|
|||
|
||||
var (
|
||||
_F_f64toa = jit.Imm(int64(native.S_f64toa))
|
||||
_F_f32toa = jit.Imm(int64(native.S_f32toa))
|
||||
_F_i64toa = jit.Imm(int64(native.S_i64toa))
|
||||
_F_u64toa = jit.Imm(int64(native.S_u64toa))
|
||||
_F_b64encode = jit.Imm(int64(_subr__b64encode))
|
||||
|
|
@ -864,8 +865,7 @@ func (self *_Assembler) _asm_OP_f32(_ *_Instr) {
|
|||
self.save_c() // SAVE $C_regs
|
||||
self.rbuf_di() // MOVQ RP, DI
|
||||
self.Emit("MOVSS" , jit.Ptr(_SP_p, 0), _X0) // MOVSS (SP.p), X0
|
||||
self.Emit("CVTSS2SD", _X0, _X0) // CVTSS2SD X0, X0
|
||||
self.call_c(_F_f64toa) // CALL_C f64toa
|
||||
self.call_c(_F_f32toa) // CALL_C f64toa
|
||||
self.Emit("ADDQ" , _AX, _RL) // ADDQ AX, RL
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ import (
|
|||
`time`
|
||||
|
||||
`github.com/bytedance/sonic/internal/rt`
|
||||
gojson `github.com/goccy/go-json`
|
||||
`github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
||||
|
|
@ -356,24 +354,6 @@ func BenchmarkEncoder_Generic_Sonic_Fast(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Generic_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Generic_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Generic_StdLib(b *testing.B) {
|
||||
_, _ = json.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
|
|
@ -401,24 +381,6 @@ func BenchmarkEncoder_Binding_Sonic_Fast(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Binding_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Binding_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Binding_StdLib(b *testing.B) {
|
||||
_, _ = json.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
|
|
@ -450,28 +412,6 @@ func BenchmarkEncoder_Parallel_Generic_Sonic_Fast(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Generic_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Generic_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Generic_StdLib(b *testing.B) {
|
||||
_, _ = json.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
|
|
@ -505,28 +445,6 @@ func BenchmarkEncoder_Parallel_Binding_Sonic_Fast(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Binding_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Binding_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Binding_StdLib(b *testing.B) {
|
||||
_, _ = json.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
|
|
@ -601,3 +519,83 @@ func BenchmarkCompact_Std(b *testing.B) {
|
|||
_ = json.Compact(dst, data)
|
||||
}
|
||||
}
|
||||
|
||||
type f64Bench struct {
|
||||
name string
|
||||
float float64
|
||||
}
|
||||
func BenchmarkEncoder_Float64(b *testing.B) {
|
||||
var bench = []f64Bench{
|
||||
{"Zero", 0},
|
||||
{"ShortDecimal", 1000},
|
||||
{"Decimal", 33909},
|
||||
{"Float", 339.7784},
|
||||
{"Exp", -5.09e75},
|
||||
{"NegExp", -5.11e-95},
|
||||
{"LongExp", 1.234567890123456e-78},
|
||||
{"Big", 123456789123456789123456789},
|
||||
|
||||
}
|
||||
maxUint := "18446744073709551615"
|
||||
for i := 1; i <= len(maxUint); i++ {
|
||||
name := strconv.FormatInt(int64(i), 10) + "-Digs"
|
||||
num, _ := strconv.ParseUint(string(maxUint[:i]), 10, 64)
|
||||
bench = append(bench, f64Bench{name, float64(num)})
|
||||
}
|
||||
for _, c := range bench {
|
||||
libs := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { _, _ = json.Marshal(c.float); for i := 0; i < b.N; i++ { _, _ = json.Marshal(c.float) }},
|
||||
}, {
|
||||
name: "Sonic",
|
||||
test: func(b *testing.B) { _, _ = Encode(c.float, 0); for i := 0; i < b.N; i++ { _, _ = Encode(c.float, 0) }},
|
||||
}}
|
||||
for _, lib := range libs {
|
||||
name := lib.name + "_" + c.name
|
||||
b.Run(name, lib.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type f32Bench struct {
|
||||
name string
|
||||
float float32
|
||||
}
|
||||
func BenchmarkEncoder_Float32(b *testing.B) {
|
||||
var bench = []f32Bench{
|
||||
{"Zero", 0},
|
||||
{"ShortDecimal", 1000},
|
||||
{"Decimal", 33909},
|
||||
{"ExactFraction", 3.375},
|
||||
{"Point", 339.7784},
|
||||
{"Exp", -5.09e25},
|
||||
{"NegExp", -5.11e-25},
|
||||
{"Shortest", 1.234567e-8},
|
||||
}
|
||||
|
||||
maxUint := "18446744073709551615"
|
||||
for i := 1; i <= len(maxUint); i++ {
|
||||
name := strconv.FormatInt(int64(i), 10) + "-Digs"
|
||||
num, _ := strconv.ParseUint(string(maxUint[:i]), 10, 64)
|
||||
bench = append(bench, f32Bench{name, float32(num)})
|
||||
}
|
||||
for _, c := range bench {
|
||||
libs := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { _, _ = json.Marshal(c.float); for i := 0; i < b.N; i++ { _, _ = json.Marshal(c.float) }},
|
||||
}, {
|
||||
name: "Sonic",
|
||||
test: func(b *testing.B) { _, _ = Encode(c.float, 0); for i := 0; i < b.N; i++ { _, _ = Encode(c.float, 0) }},
|
||||
}}
|
||||
for _, lib := range libs {
|
||||
name := lib.name + "_" + c.name
|
||||
b.Run(name, lib.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,6 @@ import (
|
|||
`strings`
|
||||
`testing`
|
||||
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
||||
|
|
@ -139,52 +138,3 @@ func BenchmarkEncodeStream_Std(b *testing.B) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncodeStream_Jsoniter(b *testing.B) {
|
||||
var o = map[string]interface{}{
|
||||
"a": `<`+strings.Repeat("1", 1024)+`>`,
|
||||
"b": json.RawMessage(` [ `+strings.Repeat(" ", 1024)+` ] `),
|
||||
}
|
||||
|
||||
b.Run("single", func(b *testing.B){
|
||||
var w = bytes.NewBuffer(nil)
|
||||
var jt = jsoniter.Config{
|
||||
ValidateJsonRawMessage: true,
|
||||
}.Froze()
|
||||
var enc = jt.NewEncoder(w)
|
||||
b.ResetTimer()
|
||||
for i:=0; i<b.N; i++ {
|
||||
_ = enc.Encode(o)
|
||||
w.Reset()
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("double", func(b *testing.B){
|
||||
var w = bytes.NewBuffer(nil)
|
||||
var jt = jsoniter.Config{
|
||||
ValidateJsonRawMessage: true,
|
||||
}.Froze()
|
||||
var enc = jt.NewEncoder(w)
|
||||
b.ResetTimer()
|
||||
for i:=0; i<b.N; i++ {
|
||||
_ = enc.Encode(o)
|
||||
_ = enc.Encode(o)
|
||||
w.Reset()
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("compatible", func(b *testing.B){
|
||||
var w = bytes.NewBuffer(nil)
|
||||
var jt = jsoniter.Config{
|
||||
ValidateJsonRawMessage: true,
|
||||
EscapeHTML: true,
|
||||
SortMapKeys: true,
|
||||
}.Froze()
|
||||
var enc = jt.NewEncoder(w)
|
||||
b.ResetTimer()
|
||||
for i:=0; i<b.N; i++ {
|
||||
_ = enc.Encode(o)
|
||||
w.Reset()
|
||||
}
|
||||
})
|
||||
}
|
||||
111
external_jsonlib_test/benchmark_test/decoder_stream_test.go
Normal file
111
external_jsonlib_test/benchmark_test/decoder_stream_test.go
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package benchmark_test
|
||||
|
||||
import (
|
||||
"io"
|
||||
`strings`
|
||||
`testing`
|
||||
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
)
|
||||
|
||||
var (
|
||||
defaultBufferSize uint = 4096
|
||||
_Single_JSON = `{"aaaaa":"` + strings.Repeat("b", int(defaultBufferSize)) + `"} { `
|
||||
_Double_JSON = `{"aaaaa":"` + strings.Repeat("b", int(defaultBufferSize)) + `"} {"11111":"` + strings.Repeat("2", int(defaultBufferSize)) + `"}`
|
||||
)
|
||||
|
||||
type HaltReader struct {
|
||||
halts map[int]bool
|
||||
buf string
|
||||
p int
|
||||
}
|
||||
|
||||
func NewHaltReader(buf string, halts map[int]bool) *HaltReader {
|
||||
return &HaltReader{
|
||||
halts: halts,
|
||||
buf: buf,
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *HaltReader) Read(p []byte) (int, error) {
|
||||
t := 0
|
||||
for ; t < len(p); {
|
||||
if self.p >= len(self.buf) {
|
||||
return t, io.EOF
|
||||
}
|
||||
if b, ok := self.halts[self.p]; b {
|
||||
self.halts[self.p] = false
|
||||
return t, nil
|
||||
} else if ok {
|
||||
delete(self.halts, self.p)
|
||||
return 0, nil
|
||||
}
|
||||
p[t] = self.buf[self.p]
|
||||
self.p++
|
||||
t++
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (self *HaltReader) Reset(buf string) {
|
||||
self.p = 0
|
||||
self.buf = buf
|
||||
}
|
||||
|
||||
var testHalts = func() map[int]bool {
|
||||
return map[int]bool{
|
||||
1: true,
|
||||
10: true,
|
||||
20: true}
|
||||
}
|
||||
|
||||
func BenchmarkDecodeStream_Jsoniter(b *testing.B) {
|
||||
b.Run("single", func(b *testing.B) {
|
||||
var str = _Single_JSON
|
||||
for i := 0; i < b.N; i++ {
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
dc := jsoniter.NewDecoder(r1)
|
||||
_ = dc.Decode(&v1)
|
||||
_ = dc.Decode(&v1)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("double", func(b *testing.B) {
|
||||
var str = _Double_JSON
|
||||
for i := 0; i < b.N; i++ {
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
dc := jsoniter.NewDecoder(r1)
|
||||
_ = dc.Decode(&v1)
|
||||
_ = dc.Decode(&v1)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("halt", func(b *testing.B) {
|
||||
var str = _Double_JSON
|
||||
for i := 0; i < b.N; i++ {
|
||||
var r1 = NewHaltReader(str, testHalts())
|
||||
var v1 map[string]interface{}
|
||||
dc := jsoniter.NewDecoder(r1)
|
||||
_ = dc.Decode(&v1)
|
||||
}
|
||||
})
|
||||
}
|
||||
185
external_jsonlib_test/benchmark_test/decoder_test.go
Normal file
185
external_jsonlib_test/benchmark_test/decoder_test.go
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package benchmark_test
|
||||
|
||||
import (
|
||||
`encoding/json`
|
||||
`testing`
|
||||
|
||||
gojson `github.com/goccy/go-json`
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = json.Unmarshal([]byte(TwitterJson), &_BindingValue)
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Generic_StdLib(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = json.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v interface{}
|
||||
_ = json.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Generic_JsonIter(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v interface{}
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Generic_GoJson(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v interface{}
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Binding_StdLib(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = json.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v TwitterStruct
|
||||
_ = json.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Binding_JsonIter(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v TwitterStruct
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Binding_GoJson(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
var v TwitterStruct
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Generic_StdLib(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = json.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v interface{}
|
||||
_ = json.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Generic_JsonIter(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v interface{}
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Generic_GoJson(b *testing.B) {
|
||||
var w interface{}
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v interface{}
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Binding_StdLib(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = json.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v TwitterStruct
|
||||
_ = json.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Binding_JsonIter(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = jsoniter.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v TwitterStruct
|
||||
_ = jsoniter.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkDecoder_Parallel_Binding_GoJson(b *testing.B) {
|
||||
var w TwitterStruct
|
||||
m := []byte(TwitterJson)
|
||||
_ = gojson.Unmarshal(m, &w)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var v TwitterStruct
|
||||
_ = gojson.Unmarshal(m, &v)
|
||||
}
|
||||
})
|
||||
}
|
||||
75
external_jsonlib_test/benchmark_test/encoder_stream_test.go
Normal file
75
external_jsonlib_test/benchmark_test/encoder_stream_test.go
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package benchmark_test
|
||||
|
||||
import (
|
||||
`bytes`
|
||||
`encoding/json`
|
||||
`strings`
|
||||
`testing`
|
||||
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
)
|
||||
|
||||
func BenchmarkEncodeStream_Jsoniter(b *testing.B) {
|
||||
var o = map[string]interface{}{
|
||||
"a": `<` + strings.Repeat("1", 1024) + `>`,
|
||||
"b": json.RawMessage(` [ ` + strings.Repeat(" ", 1024) + ` ] `),
|
||||
}
|
||||
|
||||
b.Run("single", func(b *testing.B) {
|
||||
var w = bytes.NewBuffer(nil)
|
||||
var jt = jsoniter.Config{
|
||||
ValidateJsonRawMessage: true,
|
||||
}.Froze()
|
||||
var enc = jt.NewEncoder(w)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = enc.Encode(o)
|
||||
w.Reset()
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("double", func(b *testing.B) {
|
||||
var w = bytes.NewBuffer(nil)
|
||||
var jt = jsoniter.Config{
|
||||
ValidateJsonRawMessage: true,
|
||||
}.Froze()
|
||||
var enc = jt.NewEncoder(w)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = enc.Encode(o)
|
||||
_ = enc.Encode(o)
|
||||
w.Reset()
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("compatible", func(b *testing.B) {
|
||||
var w = bytes.NewBuffer(nil)
|
||||
var jt = jsoniter.Config{
|
||||
ValidateJsonRawMessage: true,
|
||||
EscapeHTML: true,
|
||||
SortMapKeys: true,
|
||||
}.Froze()
|
||||
var enc = jt.NewEncoder(w)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = enc.Encode(o)
|
||||
w.Reset()
|
||||
}
|
||||
})
|
||||
}
|
||||
113
external_jsonlib_test/benchmark_test/encoder_test.go
Normal file
113
external_jsonlib_test/benchmark_test/encoder_test.go
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package benchmark_test
|
||||
|
||||
import (
|
||||
`encoding/json`
|
||||
`testing`
|
||||
|
||||
gojson `github.com/goccy/go-json`
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
)
|
||||
|
||||
var _GenericValue interface{}
|
||||
var _BindingValue TwitterStruct
|
||||
|
||||
func init() {
|
||||
_ = json.Unmarshal([]byte(TwitterJson), &_GenericValue)
|
||||
_ = json.Unmarshal([]byte(TwitterJson), &_BindingValue)
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Generic_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Generic_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Binding_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Binding_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Generic_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = jsoniter.Marshal(_GenericValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Generic_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = gojson.Marshal(_GenericValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Binding_JsonIter(b *testing.B) {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = jsoniter.Marshal(&_BindingValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkEncoder_Parallel_Binding_GoJson(b *testing.B) {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = gojson.Marshal(&_BindingValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
236
external_jsonlib_test/benchmark_test/parser_test.go
Normal file
236
external_jsonlib_test/benchmark_test/parser_test.go
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package benchmark_test
|
||||
|
||||
import (
|
||||
`testing`
|
||||
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/tidwall/gjson`
|
||||
)
|
||||
|
||||
func BenchmarkParser_Gjson(b *testing.B) {
|
||||
gjson.Parse(TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
_ = value.Value()
|
||||
return true
|
||||
})
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
gjson.Parse(TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
_ = value.Value()
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParser_Jsoniter(b *testing.B) {
|
||||
v := jsoniter.Get([]byte(TwitterJson)).GetInterface()
|
||||
if v == nil {
|
||||
b.Fatal(v)
|
||||
}
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = jsoniter.Get([]byte(TwitterJson)).GetInterface()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParser_Parallel_Gjson(b *testing.B) {
|
||||
gjson.Parse(TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
return true
|
||||
})
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
gjson.Parse(TwitterJson).ForEach(func(key, value gjson.Result) bool {
|
||||
if !value.Exists() {
|
||||
b.Fatal(value.Index)
|
||||
}
|
||||
_ = value.Value()
|
||||
return true
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParser_Parallel_Jsoniter(b *testing.B) {
|
||||
var bv = []byte(TwitterJson)
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
var out interface{}
|
||||
_ = jsoniter.Unmarshal(bv, &out)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Gjson(b *testing.B) {
|
||||
ast := gjson.Parse(TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
v := node.Int()
|
||||
if v != 249289491129438208 {
|
||||
b.Fatal(node)
|
||||
}
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := gjson.Parse(TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
_ = node.Int()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Jsoniter(b *testing.B) {
|
||||
data := []byte(TwitterJson)
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249289491129438208 {
|
||||
b.Fail()
|
||||
}
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
_ = ast.ToInt()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Parallel_Gjson(b *testing.B) {
|
||||
ast := gjson.Parse(TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
v := node.Int()
|
||||
if v != 249289491129438208 {
|
||||
b.Fatal(node)
|
||||
}
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := gjson.Parse(TwitterJson)
|
||||
node := ast.Get("statuses.2.id")
|
||||
_ = node.Int()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseOne_Parallel_Jsoniter(b *testing.B) {
|
||||
data := []byte(TwitterJson)
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249289491129438208 {
|
||||
b.Fail()
|
||||
}
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
data := []byte(TwitterJson)
|
||||
ast := jsoniter.Get(data, "statuses", 2, "id")
|
||||
_ = ast.ToInt()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := gjson.Parse(TwitterJson)
|
||||
node := ast.Get("statuses.3.id")
|
||||
node = ast.Get("statuses.3.user.entities.description")
|
||||
node = ast.Get("statuses.3.user.entities.url.urls")
|
||||
node = ast.Get("statuses.3.user.entities.url")
|
||||
node = ast.Get("statuses.3.user.created_at")
|
||||
node = ast.Get("statuses.3.user.name")
|
||||
node = ast.Get("statuses.3.text")
|
||||
if node.Value() == nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
data := []byte(TwitterJson)
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := jsoniter.Get(data)
|
||||
node := ast.Get("statuses", 3, "id")
|
||||
node = ast.Get("statuses", 3, "user", "entities", "description")
|
||||
node = ast.Get("statuses", 3, "user", "entities", "url", "urls")
|
||||
node = ast.Get("statuses", 3, "user", "entities", "url")
|
||||
node = ast.Get("statuses", 3, "user", "created_at")
|
||||
node = ast.Get("statuses", 3, "user", "name")
|
||||
node = ast.Get("statuses", 3, "text")
|
||||
if node.LastError() != nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Parallel_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := gjson.Parse(TwitterJson)
|
||||
node := ast.Get("statuses.3.id")
|
||||
node = ast.Get("statuses.3.user.entities.description")
|
||||
node = ast.Get("statuses.3.user.entities.url.urls")
|
||||
node = ast.Get("statuses.3.user.entities.url")
|
||||
node = ast.Get("statuses.3.user.created_at")
|
||||
node = ast.Get("statuses.3.user.name")
|
||||
node = ast.Get("statuses.3.text")
|
||||
if node.Value() == nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkParseSeven_Parallel_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
data := []byte(TwitterJson)
|
||||
ast := jsoniter.Get(data)
|
||||
node := ast.Get("statuses", 3, "id")
|
||||
node = ast.Get("statuses", 3, "user", "entities", "description")
|
||||
node = ast.Get("statuses", 3, "user", "entities", "url", "urls")
|
||||
node = ast.Get("statuses", 3, "user", "entities", "url")
|
||||
node = ast.Get("statuses", 3, "user", "created_at")
|
||||
node = ast.Get("statuses", 3, "user", "name")
|
||||
node = ast.Get("statuses", 3, "text")
|
||||
if node.LastError() != nil {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
141
external_jsonlib_test/benchmark_test/search_test.go
Normal file
141
external_jsonlib_test/benchmark_test/search_test.go
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package benchmark_test
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`math`
|
||||
`testing`
|
||||
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/tidwall/gjson`
|
||||
`github.com/tidwall/sjson`
|
||||
)
|
||||
|
||||
func BenchmarkGetOne_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := gjson.Get(TwitterJson, "statuses.3.id")
|
||||
node := ast.Int()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
data := []byte(TwitterJson)
|
||||
for i := 0; i < b.N; i++ {
|
||||
ast := jsoniter.Get(data, "statuses", 3, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Parallel_Gjson(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := gjson.Get(TwitterJson, "statuses.3.id")
|
||||
node := ast.Int()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkGetOne_Parallel_Jsoniter(b *testing.B) {
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
data := []byte(TwitterJson)
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
ast := jsoniter.Get(data, "statuses", 3, "id")
|
||||
node := ast.ToInt()
|
||||
if node != 249279667666817024 {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Sjson(b *testing.B) {
|
||||
path := fmt.Sprintf("%s.%d.%s", "statuses", 3, "id")
|
||||
_, err := sjson.Set(TwitterJson, path, math.MaxInt32)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
sjson.Set(TwitterJson, path, math.MaxInt32)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Jsoniter(b *testing.B) {
|
||||
data := []byte(TwitterJson)
|
||||
node, ok := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
if !ok {
|
||||
b.Fatal(node)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(len(data)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
node, _ := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
node["id"] = math.MaxInt32
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Parallel_Sjson(b *testing.B) {
|
||||
path := fmt.Sprintf("%s.%d.%s", "statuses", 3, "id")
|
||||
_, err := sjson.Set(TwitterJson, path, math.MaxInt32)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(TwitterJson)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
sjson.Set(TwitterJson, path, math.MaxInt32)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSetOne_Parallel_Jsoniter(b *testing.B) {
|
||||
data := []byte(TwitterJson)
|
||||
node, ok := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
if !ok {
|
||||
b.Fatal(node)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(len(data)))
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
node, _ := jsoniter.Get(data, "statuses", 3).GetInterface().(map[string]interface{})
|
||||
node["id"] = math.MaxInt32
|
||||
}
|
||||
})
|
||||
}
|
||||
551
external_jsonlib_test/benchmark_test/testdata_test.go
Normal file
551
external_jsonlib_test/benchmark_test/testdata_test.go
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package benchmark_test
|
||||
|
||||
const TwitterJson = `{
|
||||
"statuses": [
|
||||
{
|
||||
"coordinates": null,
|
||||
"favorited": false,
|
||||
"truncated": false,
|
||||
"created_at": "Mon Sep 24 03:35:21 +0000 2012",
|
||||
"id_str": "250075927172759552",
|
||||
"entities": {
|
||||
"urls": [
|
||||
|
||||
],
|
||||
"hashtags": [
|
||||
{
|
||||
"text": "freebandnames",
|
||||
"indices": [
|
||||
20,
|
||||
34
|
||||
]
|
||||
}
|
||||
],
|
||||
"user_mentions": [
|
||||
|
||||
]
|
||||
},
|
||||
"in_reply_to_user_id_str": null,
|
||||
"contributors": null,
|
||||
"text": "Aggressive Ponytail #freebandnames",
|
||||
"metadata": {
|
||||
"iso_language_code": "en",
|
||||
"result_type": "recent"
|
||||
},
|
||||
"retweet_count": 0,
|
||||
"in_reply_to_status_id_str": null,
|
||||
"id": 250075927172759552,
|
||||
"geo": null,
|
||||
"retweeted": false,
|
||||
"in_reply_to_user_id": null,
|
||||
"place": null,
|
||||
"user": {
|
||||
"profile_sidebar_fill_color": "DDEEF6",
|
||||
"profile_sidebar_border_color": "C0DEED",
|
||||
"profile_background_tile": false,
|
||||
"name": "Sean Cummings",
|
||||
"profile_image_url": "https://a0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
|
||||
"created_at": "Mon Apr 26 06:01:55 +0000 2010",
|
||||
"location": "LA, CA",
|
||||
"follow_request_sent": null,
|
||||
"profile_link_color": "0084B4",
|
||||
"is_translator": false,
|
||||
"id_str": "137238150",
|
||||
"entities": {
|
||||
"url": {
|
||||
"urls": [
|
||||
{
|
||||
"expanded_url": null,
|
||||
"url": "",
|
||||
"indices": [
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"urls": [
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
"default_profile": true,
|
||||
"contributors_enabled": false,
|
||||
"favourites_count": 0,
|
||||
"url": null,
|
||||
"profile_image_url_https": "https://si0.twimg.com/profile_images/2359746665/1v6zfgqo8g0d3mk7ii5s_normal.jpeg",
|
||||
"utc_offset": -28800,
|
||||
"id": 137238150,
|
||||
"profile_use_background_image": true,
|
||||
"listed_count": 2,
|
||||
"profile_text_color": "333333",
|
||||
"lang": "en",
|
||||
"followers_count": 70,
|
||||
"protected": false,
|
||||
"notifications": null,
|
||||
"profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme1/bg.png",
|
||||
"profile_background_color": "C0DEED",
|
||||
"verified": false,
|
||||
"geo_enabled": true,
|
||||
"time_zone": "Pacific Time (US & Canada)",
|
||||
"description": "Born 330 Live 310",
|
||||
"default_profile_image": false,
|
||||
"profile_background_image_url": "https://a0.twimg.com/images/themes/theme1/bg.png",
|
||||
"statuses_count": 579,
|
||||
"friends_count": 110,
|
||||
"following": null,
|
||||
"show_all_inline_media": false,
|
||||
"screen_name": "sean_cummings"
|
||||
},
|
||||
"in_reply_to_screen_name": null,
|
||||
"source": "<a href=\"//itunes.apple.com/us/app/twitter/id409789998?mt=12%5C%22\" rel=\"\\\"nofollow\\\"\">Twitter for Mac</a>",
|
||||
"in_reply_to_status_id": null
|
||||
},
|
||||
{
|
||||
"coordinates": null,
|
||||
"favorited": false,
|
||||
"truncated": false,
|
||||
"created_at": "Fri Sep 21 23:40:54 +0000 2012",
|
||||
"id_str": "249292149810667520",
|
||||
"entities": {
|
||||
"urls": [
|
||||
|
||||
],
|
||||
"hashtags": [
|
||||
{
|
||||
"text": "FreeBandNames",
|
||||
"indices": [
|
||||
20,
|
||||
34
|
||||
]
|
||||
}
|
||||
],
|
||||
"user_mentions": [
|
||||
|
||||
]
|
||||
},
|
||||
"in_reply_to_user_id_str": null,
|
||||
"contributors": null,
|
||||
"text": "Thee Namaste Nerdz. #FreeBandNames",
|
||||
"metadata": {
|
||||
"iso_language_code": "pl",
|
||||
"result_type": "recent"
|
||||
},
|
||||
"retweet_count": 0,
|
||||
"in_reply_to_status_id_str": null,
|
||||
"id": 249292149810667520,
|
||||
"geo": null,
|
||||
"retweeted": false,
|
||||
"in_reply_to_user_id": null,
|
||||
"place": null,
|
||||
"user": {
|
||||
"profile_sidebar_fill_color": "DDFFCC",
|
||||
"profile_sidebar_border_color": "BDDCAD",
|
||||
"profile_background_tile": true,
|
||||
"name": "Chaz Martenstein",
|
||||
"profile_image_url": "https://a0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
|
||||
"created_at": "Tue Apr 07 19:05:07 +0000 2009",
|
||||
"location": "Durham, NC",
|
||||
"follow_request_sent": null,
|
||||
"profile_link_color": "0084B4",
|
||||
"is_translator": false,
|
||||
"id_str": "29516238",
|
||||
"entities": {
|
||||
"url": {
|
||||
"urls": [
|
||||
{
|
||||
"expanded_url": null,
|
||||
"url": "https://bullcityrecords.com/wnng/",
|
||||
"indices": [
|
||||
0,
|
||||
32
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"urls": [
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
"default_profile": false,
|
||||
"contributors_enabled": false,
|
||||
"favourites_count": 8,
|
||||
"url": "https://bullcityrecords.com/wnng/",
|
||||
"profile_image_url_https": "https://si0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
|
||||
"utc_offset": -18000,
|
||||
"id": 29516238,
|
||||
"profile_use_background_image": true,
|
||||
"listed_count": 118,
|
||||
"profile_text_color": "333333",
|
||||
"lang": "en",
|
||||
"followers_count": 2052,
|
||||
"protected": false,
|
||||
"notifications": null,
|
||||
"profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/9423277/background_tile.bmp",
|
||||
"profile_background_color": "9AE4E8",
|
||||
"verified": false,
|
||||
"geo_enabled": false,
|
||||
"time_zone": "Eastern Time (US & Canada)",
|
||||
"description": "You will come to Durham, North Carolina. I will sell you some records then, here in Durham, North Carolina. Fun will happen.",
|
||||
"default_profile_image": false,
|
||||
"profile_background_image_url": "https://a0.twimg.com/profile_background_images/9423277/background_tile.bmp",
|
||||
"statuses_count": 7579,
|
||||
"friends_count": 348,
|
||||
"following": null,
|
||||
"show_all_inline_media": true,
|
||||
"screen_name": "bullcityrecords"
|
||||
},
|
||||
"in_reply_to_screen_name": null,
|
||||
"source": "web",
|
||||
"in_reply_to_status_id": null
|
||||
},
|
||||
{
|
||||
"coordinates": null,
|
||||
"favorited": false,
|
||||
"truncated": false,
|
||||
"created_at": "Fri Sep 21 23:30:20 +0000 2012",
|
||||
"id_str": "249289491129438208",
|
||||
"entities": {
|
||||
"urls": [
|
||||
|
||||
],
|
||||
"hashtags": [
|
||||
{
|
||||
"text": "freebandnames",
|
||||
"indices": [
|
||||
29,
|
||||
43
|
||||
]
|
||||
}
|
||||
],
|
||||
"user_mentions": [
|
||||
|
||||
]
|
||||
},
|
||||
"in_reply_to_user_id_str": null,
|
||||
"contributors": null,
|
||||
"text": "Mexican Heaven, Mexican Hell #freebandnames",
|
||||
"metadata": {
|
||||
"iso_language_code": "en",
|
||||
"result_type": "recent"
|
||||
},
|
||||
"retweet_count": 0,
|
||||
"in_reply_to_status_id_str": null,
|
||||
"id": 249289491129438208,
|
||||
"geo": null,
|
||||
"retweeted": false,
|
||||
"in_reply_to_user_id": null,
|
||||
"place": null,
|
||||
"user": {
|
||||
"profile_sidebar_fill_color": "99CC33",
|
||||
"profile_sidebar_border_color": "829D5E",
|
||||
"profile_background_tile": false,
|
||||
"name": "Thomas John Wakeman",
|
||||
"profile_image_url": "https://a0.twimg.com/profile_images/2219333930/Froggystyle_normal.png",
|
||||
"created_at": "Tue Sep 01 21:21:35 +0000 2009",
|
||||
"location": "Kingston New York",
|
||||
"follow_request_sent": null,
|
||||
"profile_link_color": "D02B55",
|
||||
"is_translator": false,
|
||||
"id_str": "70789458",
|
||||
"entities": {
|
||||
"url": {
|
||||
"urls": [
|
||||
{
|
||||
"expanded_url": null,
|
||||
"url": "",
|
||||
"indices": [
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"urls": [
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
"default_profile": false,
|
||||
"contributors_enabled": false,
|
||||
"favourites_count": 19,
|
||||
"url": null,
|
||||
"profile_image_url_https": "https://si0.twimg.com/profile_images/2219333930/Froggystyle_normal.png",
|
||||
"utc_offset": -18000,
|
||||
"id": 70789458,
|
||||
"profile_use_background_image": true,
|
||||
"listed_count": 1,
|
||||
"profile_text_color": "3E4415",
|
||||
"lang": "en",
|
||||
"followers_count": 63,
|
||||
"protected": false,
|
||||
"notifications": null,
|
||||
"profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme5/bg.gif",
|
||||
"profile_background_color": "352726",
|
||||
"verified": false,
|
||||
"geo_enabled": false,
|
||||
"time_zone": "Eastern Time (US & Canada)",
|
||||
"description": "Science Fiction Writer, sort of. Likes Superheroes, Mole People, Alt. Timelines.",
|
||||
"default_profile_image": false,
|
||||
"profile_background_image_url": "https://a0.twimg.com/images/themes/theme5/bg.gif",
|
||||
"statuses_count": 1048,
|
||||
"friends_count": 63,
|
||||
"following": null,
|
||||
"show_all_inline_media": false,
|
||||
"screen_name": "MonkiesFist"
|
||||
},
|
||||
"in_reply_to_screen_name": null,
|
||||
"source": "web",
|
||||
"in_reply_to_status_id": null
|
||||
},
|
||||
{
|
||||
"coordinates": null,
|
||||
"favorited": false,
|
||||
"truncated": false,
|
||||
"created_at": "Fri Sep 21 22:51:18 +0000 2012",
|
||||
"id_str": "249279667666817024",
|
||||
"entities": {
|
||||
"urls": [
|
||||
|
||||
],
|
||||
"hashtags": [
|
||||
{
|
||||
"text": "freebandnames",
|
||||
"indices": [
|
||||
20,
|
||||
34
|
||||
]
|
||||
}
|
||||
],
|
||||
"user_mentions": [
|
||||
|
||||
]
|
||||
},
|
||||
"in_reply_to_user_id_str": null,
|
||||
"contributors": null,
|
||||
"text": "The Foolish Mortals #freebandnames",
|
||||
"metadata": {
|
||||
"iso_language_code": "en",
|
||||
"result_type": "recent"
|
||||
},
|
||||
"retweet_count": 0,
|
||||
"in_reply_to_status_id_str": null,
|
||||
"id": 249279667666817024,
|
||||
"geo": null,
|
||||
"retweeted": false,
|
||||
"in_reply_to_user_id": null,
|
||||
"place": null,
|
||||
"user": {
|
||||
"profile_sidebar_fill_color": "BFAC83",
|
||||
"profile_sidebar_border_color": "615A44",
|
||||
"profile_background_tile": true,
|
||||
"name": "Marty Elmer",
|
||||
"profile_image_url": "https://a0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png",
|
||||
"created_at": "Mon May 04 00:05:00 +0000 2009",
|
||||
"location": "Wisconsin, USA",
|
||||
"follow_request_sent": null,
|
||||
"profile_link_color": "3B2A26",
|
||||
"is_translator": false,
|
||||
"id_str": "37539828",
|
||||
"entities": {
|
||||
"url": {
|
||||
"urls": [
|
||||
{
|
||||
"expanded_url": null,
|
||||
"url": "https://www.omnitarian.me",
|
||||
"indices": [
|
||||
0,
|
||||
24
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"urls": [
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
"default_profile": false,
|
||||
"contributors_enabled": false,
|
||||
"favourites_count": 647,
|
||||
"url": "https://www.omnitarian.me",
|
||||
"profile_image_url_https": "https://si0.twimg.com/profile_images/1629790393/shrinker_2000_trans_normal.png",
|
||||
"utc_offset": -21600,
|
||||
"id": 37539828,
|
||||
"profile_use_background_image": true,
|
||||
"listed_count": 52,
|
||||
"profile_text_color": "000000",
|
||||
"lang": "en",
|
||||
"followers_count": 608,
|
||||
"protected": false,
|
||||
"notifications": null,
|
||||
"profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/106455659/rect6056-9.png",
|
||||
"profile_background_color": "EEE3C4",
|
||||
"verified": false,
|
||||
"geo_enabled": false,
|
||||
"time_zone": "Central Time (US & Canada)",
|
||||
"description": "Cartoonist, Illustrator, and T-Shirt connoisseur",
|
||||
"default_profile_image": false,
|
||||
"profile_background_image_url": "https://a0.twimg.com/profile_background_images/106455659/rect6056-9.png",
|
||||
"statuses_count": 3575,
|
||||
"friends_count": 249,
|
||||
"following": null,
|
||||
"show_all_inline_media": true,
|
||||
"screen_name": "Omnitarian"
|
||||
},
|
||||
"in_reply_to_screen_name": null,
|
||||
"source": "<a href=\"//twitter.com/download/iphone%5C%22\" rel=\"\\\"nofollow\\\"\">Twitter for iPhone</a>",
|
||||
"in_reply_to_status_id": null
|
||||
}
|
||||
],
|
||||
"search_metadata": {
|
||||
"max_id": 250126199840518145,
|
||||
"since_id": 24012619984051000,
|
||||
"refresh_url": "?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1",
|
||||
"next_results": "?max_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=mixed",
|
||||
"count": 4,
|
||||
"completed_in": 0.035,
|
||||
"since_id_str": "24012619984051000",
|
||||
"query": "%23freebandnames",
|
||||
"max_id_str": "250126199840518145"
|
||||
}
|
||||
}`
|
||||
|
||||
type TwitterStruct struct {
|
||||
Statuses []Statuses `json:"statuses"`
|
||||
SearchMetadata SearchMetadata `json:"search_metadata"`
|
||||
}
|
||||
|
||||
type Hashtags struct {
|
||||
Text string `json:"text"`
|
||||
Indices []int `json:"indices"`
|
||||
}
|
||||
|
||||
type Entities struct {
|
||||
Urls []interface{} `json:"urls"`
|
||||
Hashtags []Hashtags `json:"hashtags"`
|
||||
UserMentions []interface{} `json:"user_mentions"`
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
IsoLanguageCode string `json:"iso_language_code"`
|
||||
ResultType string `json:"result_type"`
|
||||
}
|
||||
|
||||
type Urls struct {
|
||||
ExpandedURL interface{} `json:"expanded_url"`
|
||||
URL string `json:"url"`
|
||||
Indices []int `json:"indices"`
|
||||
}
|
||||
|
||||
type URL struct {
|
||||
Urls []Urls `json:"urls"`
|
||||
}
|
||||
|
||||
type Description struct {
|
||||
Urls []interface{} `json:"urls"`
|
||||
}
|
||||
|
||||
type UserEntities struct {
|
||||
URL URL `json:"url"`
|
||||
Description Description `json:"description"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ProfileSidebarFillColor string `json:"profile_sidebar_fill_color"`
|
||||
ProfileSidebarBorderColor string `json:"profile_sidebar_border_color"`
|
||||
ProfileBackgroundTile bool `json:"profile_background_tile"`
|
||||
Name string `json:"name"`
|
||||
ProfileImageURL string `json:"profile_image_url"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Location string `json:"location"`
|
||||
FollowRequestSent interface{} `json:"follow_request_sent"`
|
||||
ProfileLinkColor string `json:"profile_link_color"`
|
||||
IsTranslator bool `json:"is_translator"`
|
||||
IDStr string `json:"id_str"`
|
||||
Entities UserEntities `json:"entities"`
|
||||
DefaultProfile bool `json:"default_profile"`
|
||||
ContributorsEnabled bool `json:"contributors_enabled"`
|
||||
FavouritesCount int `json:"favourites_count"`
|
||||
URL interface{} `json:"url"`
|
||||
ProfileImageURLHTTPS string `json:"profile_image_url_https"`
|
||||
UtcOffset int `json:"utc_offset"`
|
||||
ID int `json:"id"`
|
||||
ProfileUseBackgroundImage bool `json:"profile_use_background_image"`
|
||||
ListedCount int `json:"listed_count"`
|
||||
ProfileTextColor string `json:"profile_text_color"`
|
||||
Lang string `json:"lang"`
|
||||
FollowersCount int `json:"followers_count"`
|
||||
Protected bool `json:"protected"`
|
||||
Notifications interface{} `json:"notifications"`
|
||||
ProfileBackgroundImageURLHTTPS string `json:"profile_background_image_url_https"`
|
||||
ProfileBackgroundColor string `json:"profile_background_color"`
|
||||
Verified bool `json:"verified"`
|
||||
GeoEnabled bool `json:"geo_enabled"`
|
||||
TimeZone string `json:"time_zone"`
|
||||
Description string `json:"description"`
|
||||
DefaultProfileImage bool `json:"default_profile_image"`
|
||||
ProfileBackgroundImageURL string `json:"profile_background_image_url"`
|
||||
StatusesCount int `json:"statuses_count"`
|
||||
FriendsCount int `json:"friends_count"`
|
||||
Following interface{} `json:"following"`
|
||||
ShowAllInlineMedia bool `json:"show_all_inline_media"`
|
||||
ScreenName string `json:"screen_name"`
|
||||
}
|
||||
|
||||
type Statuses struct {
|
||||
Coordinates interface{} `json:"coordinates"`
|
||||
Favorited bool `json:"favorited"`
|
||||
Truncated bool `json:"truncated"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
IDStr string `json:"id_str"`
|
||||
Entities Entities `json:"entities"`
|
||||
InReplyToUserIDStr interface{} `json:"in_reply_to_user_id_str"`
|
||||
Contributors interface{} `json:"contributors"`
|
||||
Text string `json:"text"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
RetweetCount int `json:"retweet_count"`
|
||||
InReplyToStatusIDStr interface{} `json:"in_reply_to_status_id_str"`
|
||||
ID int64 `json:"id"`
|
||||
Geo interface{} `json:"geo"`
|
||||
Retweeted bool `json:"retweeted"`
|
||||
InReplyToUserID interface{} `json:"in_reply_to_user_id"`
|
||||
Place interface{} `json:"place"`
|
||||
User User `json:"user"`
|
||||
InReplyToScreenName interface{} `json:"in_reply_to_screen_name"`
|
||||
Source string `json:"source"`
|
||||
InReplyToStatusID interface{} `json:"in_reply_to_status_id"`
|
||||
}
|
||||
|
||||
type SearchMetadata struct {
|
||||
MaxID int64 `json:"max_id"`
|
||||
SinceID int64 `json:"since_id"`
|
||||
RefreshURL string `json:"refresh_url"`
|
||||
NextResults string `json:"next_results"`
|
||||
Count int `json:"count"`
|
||||
CompletedIn float64 `json:"completed_in"`
|
||||
SinceIDStr string `json:"since_id_str"`
|
||||
Query string `json:"query"`
|
||||
MaxIDStr string `json:"max_id_str"`
|
||||
}
|
||||
26
external_jsonlib_test/go.mod
Normal file
26
external_jsonlib_test/go.mod
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
module github.com/bytedance/sonic/external_jsonlib_test
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.4.0
|
||||
github.com/goccy/go-json v0.9.11
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/tidwall/gjson v1.14.3
|
||||
github.com/tidwall/sjson v1.2.5
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
50
external_jsonlib_test/go.sum
Normal file
50
external_jsonlib_test/go.sum
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
github.com/bytedance/sonic v1.4.0 h1:d6vgPhwgHfpmEiz/9Fzea9fGzWY7RO1TQEySBiRwDLY=
|
||||
github.com/bytedance/sonic v1.4.0/go.mod h1:V973WhNhGmvHxW6nQmsHEfHaoU9F3zTF+93rH03hcUQ=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 h1:1sDoSuDPWzhkdzNVxCxtIaKiAe96ESVPv8coGwc1gZ4=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/goccy/go-json v0.9.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
|
||||
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
|
@ -14,13 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sonic
|
||||
package unit_test
|
||||
|
||||
import (
|
||||
`bytes`
|
||||
`encoding/json`
|
||||
`testing`
|
||||
|
||||
`github.com/bytedance/sonic`
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
|
@ -33,7 +34,7 @@ func TestCompatMarshalDefault(t *testing.T){
|
|||
var obj = map[string]interface{}{
|
||||
"c": json.RawMessage("[\"<&>\"]"),
|
||||
}
|
||||
sout, serr := ConfigDefault.Marshal(obj)
|
||||
sout, serr := sonic.ConfigDefault.Marshal(obj)
|
||||
jout, jerr := jt.Marshal(obj)
|
||||
require.Equal(t, jerr, serr)
|
||||
require.Equal(t, string(jout), string(sout))
|
||||
|
|
@ -41,7 +42,7 @@ func TestCompatMarshalDefault(t *testing.T){
|
|||
// obj = map[string]interface{}{
|
||||
// "a": json.RawMessage(" [} "),
|
||||
// }
|
||||
// sout, serr = ConfigDefault.Marshal(obj)
|
||||
// sout, serr = sonic.ConfigDefault.Marshal(obj)
|
||||
// jout, jerr = json.Marshal(obj)
|
||||
// require.NotNil(t, jerr)
|
||||
// require.NotNil(t, serr)
|
||||
|
|
@ -50,7 +51,7 @@ func TestCompatMarshalDefault(t *testing.T){
|
|||
obj = map[string]interface{}{
|
||||
"a": json.RawMessage("1"),
|
||||
}
|
||||
sout, serr = ConfigDefault.MarshalIndent(obj, "", " ")
|
||||
sout, serr = sonic.ConfigDefault.MarshalIndent(obj, "", " ")
|
||||
jout, jerr = jt.MarshalIndent(obj, "", " ")
|
||||
require.Equal(t, jerr, serr)
|
||||
require.Equal(t, string(jout), string(sout))
|
||||
|
|
@ -62,7 +63,7 @@ func TestCompatMarshalStd(t *testing.T) {
|
|||
"c": json.RawMessage(" [ \"<&>\" ] "),
|
||||
"b": json.RawMessage(" [ ] "),
|
||||
}
|
||||
sout, serr := ConfigStd.Marshal(obj)
|
||||
sout, serr := sonic.ConfigStd.Marshal(obj)
|
||||
jout, jerr := json.Marshal(obj)
|
||||
require.Equal(t, jerr, serr)
|
||||
require.Equal(t, string(jout), string(sout))
|
||||
|
|
@ -70,7 +71,7 @@ func TestCompatMarshalStd(t *testing.T) {
|
|||
obj = map[string]interface{}{
|
||||
"a": json.RawMessage(" [} "),
|
||||
}
|
||||
sout, serr = ConfigStd.Marshal(obj)
|
||||
sout, serr = sonic.ConfigStd.Marshal(obj)
|
||||
jout, jerr = json.Marshal(obj)
|
||||
require.NotNil(t, jerr)
|
||||
require.NotNil(t, serr)
|
||||
|
|
@ -79,7 +80,7 @@ func TestCompatMarshalStd(t *testing.T) {
|
|||
obj = map[string]interface{}{
|
||||
"a": json.RawMessage("1"),
|
||||
}
|
||||
sout, serr = ConfigStd.MarshalIndent(obj, "xxxx", " ")
|
||||
sout, serr = sonic.ConfigStd.MarshalIndent(obj, "xxxx", " ")
|
||||
jout, jerr = json.MarshalIndent(obj, "xxxx", " ")
|
||||
require.Equal(t, jerr, serr)
|
||||
require.Equal(t, string(jout), string(sout))
|
||||
|
|
@ -90,7 +91,7 @@ func TestCompatUnmarshalDefault(t *testing.T) {
|
|||
var jobj = map[string]interface{}{}
|
||||
var data = []byte(`{"a":-0}`)
|
||||
var str = string(data)
|
||||
serr := ConfigDefault.UnmarshalFromString(str, &sobj)
|
||||
serr := sonic.ConfigDefault.UnmarshalFromString(str, &sobj)
|
||||
jerr := jt.UnmarshalFromString(str, &jobj)
|
||||
require.Equal(t, jerr, serr)
|
||||
require.Equal(t, jobj, sobj)
|
||||
|
|
@ -98,7 +99,7 @@ func TestCompatUnmarshalDefault(t *testing.T) {
|
|||
x := struct{A json.Number}{}
|
||||
y := struct{A json.Number}{}
|
||||
data = []byte(`{"A":"1", "B":-1}`)
|
||||
serr = ConfigDefault.Unmarshal(data, &x)
|
||||
serr = sonic.ConfigDefault.Unmarshal(data, &x)
|
||||
jerr = jt.Unmarshal(data, &y)
|
||||
require.Equal(t, jerr, serr)
|
||||
require.Equal(t, y, x)
|
||||
|
|
@ -109,7 +110,7 @@ func TestCompatUnmarshalStd(t *testing.T) {
|
|||
var jobj = map[string]interface{}{}
|
||||
var data = []byte(`{"a":1.00000001E-10}`)
|
||||
var str = string(data)
|
||||
serr := ConfigStd.UnmarshalFromString(str, &sobj)
|
||||
serr := sonic.ConfigStd.UnmarshalFromString(str, &sobj)
|
||||
jerr := json.Unmarshal(data, &jobj)
|
||||
require.Equal(t, jerr, serr)
|
||||
require.Equal(t, jobj, sobj)
|
||||
|
|
@ -119,7 +120,7 @@ func TestCompatUnmarshalStd(t *testing.T) {
|
|||
sobj = map[string]interface{}{}
|
||||
jobj = map[string]interface{}{}
|
||||
data = []byte(`{"a":1}`)
|
||||
cfg := Config{
|
||||
cfg := sonic.Config{
|
||||
UseNumber: true,
|
||||
}.Froze()
|
||||
serr = cfg.Unmarshal(data, &sobj)
|
||||
|
|
@ -132,7 +133,7 @@ func TestCompatUnmarshalStd(t *testing.T) {
|
|||
x := struct{A json.Number}{}
|
||||
y := struct{A json.Number}{}
|
||||
data = []byte(`{"A":"1", "B":-1}`)
|
||||
cfg = Config{
|
||||
cfg = sonic.Config{
|
||||
DisallowUnknownFields: true,
|
||||
}.Froze()
|
||||
serr = cfg.Unmarshal(data, &x)
|
||||
|
|
@ -152,7 +153,7 @@ func TestCompatEncoderDefault(t *testing.T) {
|
|||
var w1 = bytes.NewBuffer(nil)
|
||||
var w2 = bytes.NewBuffer(nil)
|
||||
var enc1 = jt.NewEncoder(w1)
|
||||
var enc2 = ConfigDefault.NewEncoder(w2)
|
||||
var enc2 = sonic.ConfigDefault.NewEncoder(w2)
|
||||
|
||||
require.Nil(t, enc1.Encode(o))
|
||||
require.Nil(t, enc2.Encode(o))
|
||||
|
|
@ -183,7 +184,7 @@ func TestCompatEncoderStd(t *testing.T) {
|
|||
var w1 = bytes.NewBuffer(nil)
|
||||
var w2 = bytes.NewBuffer(nil)
|
||||
var enc1 = json.NewEncoder(w1)
|
||||
var enc2 = ConfigStd.NewEncoder(w2)
|
||||
var enc2 = sonic.ConfigStd.NewEncoder(w2)
|
||||
|
||||
require.Nil(t, enc1.Encode(o))
|
||||
require.Nil(t, enc2.Encode(o))
|
||||
|
|
@ -213,7 +214,7 @@ func TestCompatDecoderStd(t *testing.T) {
|
|||
var w1 = bytes.NewBuffer([]byte(s))
|
||||
var w2 = bytes.NewBuffer([]byte(s))
|
||||
var enc1 = json.NewDecoder(w1)
|
||||
var enc2 = ConfigStd.NewDecoder(w2)
|
||||
var enc2 = sonic.ConfigStd.NewDecoder(w2)
|
||||
|
||||
require.Equal(t, enc1.More(), enc2.More())
|
||||
require.Nil(t, enc1.Decode(&o1))
|
||||
|
|
@ -238,7 +239,7 @@ func TestCompatDecoderDefault(t *testing.T) {
|
|||
var w1 = bytes.NewBuffer([]byte(s))
|
||||
var w2 = bytes.NewBuffer([]byte(s))
|
||||
var enc1 = jt.NewDecoder(w1)
|
||||
var enc2 = ConfigDefault.NewDecoder(w2)
|
||||
var enc2 = sonic.ConfigDefault.NewDecoder(w2)
|
||||
|
||||
require.Equal(t, enc1.More(), enc2.More())
|
||||
require.Nil(t, enc1.Decode(&o1))
|
||||
|
|
@ -14,11 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package ast
|
||||
package unit_test
|
||||
|
||||
import (
|
||||
`testing`
|
||||
|
||||
`github.com/bytedance/sonic/ast`
|
||||
jsoniter `github.com/json-iterator/go`
|
||||
`github.com/stretchr/testify/require`
|
||||
`github.com/tidwall/gjson`
|
||||
|
|
@ -35,8 +36,8 @@ func TestNotFoud(t *testing.T) {
|
|||
require.True(t, ga.Type == gjson.Null)
|
||||
require.Equal(t, false, ga.Bool())
|
||||
|
||||
sa, err := NewSearcher(data).GetByPath("b")
|
||||
require.True(t, sa.Type() == V_NONE)
|
||||
sa, err := ast.NewSearcher(data).GetByPath("b")
|
||||
require.True(t, sa.Type() == ast.V_NONE)
|
||||
require.Error(t, err)
|
||||
sv, err := sa.Bool()
|
||||
require.Error(t, err)
|
||||
|
|
@ -54,8 +55,8 @@ func TestNull(t *testing.T) {
|
|||
require.True(t, ga.Type == gjson.Null)
|
||||
require.Equal(t, false, ga.Bool())
|
||||
|
||||
sa, err := NewSearcher(data).GetByPath("b")
|
||||
require.True(t, sa.Type() == V_NULL)
|
||||
sa, err := ast.NewSearcher(data).GetByPath("b")
|
||||
require.True(t, sa.Type() == ast.V_NULL)
|
||||
require.NoError(t, err)
|
||||
sv, err := sa.Bool()
|
||||
require.NoError(t, err)
|
||||
231
external_jsonlib_test/unit_test/decoder_stream_test.go
Normal file
231
external_jsonlib_test/unit_test/decoder_stream_test.go
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package unit_test
|
||||
|
||||
import (
|
||||
`io`
|
||||
`strings`
|
||||
`testing`
|
||||
|
||||
`github.com/bytedance/sonic/decoder`
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
`github.com/stretchr/testify/assert`
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
||||
var (
|
||||
defaultBufferSize uint = 4096
|
||||
_Single_JSON = `{"aaaaa":"` + strings.Repeat("b", int(defaultBufferSize)) + `"} { `
|
||||
_Triple_JSON = `{"aaaaa":"` + strings.Repeat("b", int(defaultBufferSize)) + `"}{ } {"11111":"` +
|
||||
strings.Repeat("2", int(defaultBufferSize)) + `"} b {}`
|
||||
)
|
||||
|
||||
func TestDecodeSingle(t *testing.T) {
|
||||
var str = _Single_JSON
|
||||
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
var r2 = strings.NewReader(str)
|
||||
var v2 map[string]interface{}
|
||||
var d2 = decoder.NewStreamDecoder(r2)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es1 := d1.Decode(&v1)
|
||||
ee1 := d2.Decode(&v2)
|
||||
assert.Equal(t, es1, ee1)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
}
|
||||
|
||||
func TestDecodeMulti(t *testing.T) {
|
||||
var str = _Triple_JSON
|
||||
|
||||
var r1 = strings.NewReader(str)
|
||||
var v1 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
var r2 = strings.NewReader(str)
|
||||
var v2 map[string]interface{}
|
||||
var d2 = decoder.NewStreamDecoder(r2)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es1 := d1.Decode(&v1)
|
||||
ee1 := d2.Decode(&v2)
|
||||
assert.Equal(t, es1, ee1)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es4 := d1.Decode(&v1)
|
||||
ee4 := d2.Decode(&v2)
|
||||
assert.Equal(t, es4, ee4)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es2 := d1.Decode(&v1)
|
||||
ee2 := d2.Decode(&v2)
|
||||
assert.Equal(t, es2, ee2)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
// fmt.Printf("v:%#v\n", v1)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es5 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es5)
|
||||
ee5 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee5)
|
||||
}
|
||||
|
||||
type HaltReader struct {
|
||||
halts map[int]bool
|
||||
buf string
|
||||
p int
|
||||
}
|
||||
|
||||
func NewHaltReader(buf string, halts map[int]bool) *HaltReader {
|
||||
return &HaltReader{
|
||||
halts: halts,
|
||||
buf: buf,
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *HaltReader) Read(p []byte) (int, error) {
|
||||
t := 0
|
||||
for ; t < len(p); {
|
||||
if self.p >= len(self.buf) {
|
||||
return t, io.EOF
|
||||
}
|
||||
if b, ok := self.halts[self.p]; b {
|
||||
self.halts[self.p] = false
|
||||
return t, nil
|
||||
} else if ok {
|
||||
delete(self.halts, self.p)
|
||||
return 0, nil
|
||||
}
|
||||
p[t] = self.buf[self.p]
|
||||
self.p++
|
||||
t++
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (self *HaltReader) Reset(buf string) {
|
||||
self.p = 0
|
||||
self.buf = buf
|
||||
}
|
||||
|
||||
var testHalts = func() map[int]bool {
|
||||
return map[int]bool{
|
||||
1: true,
|
||||
10: true,
|
||||
20: true}
|
||||
}
|
||||
|
||||
func TestDecodeHalt(t *testing.T) {
|
||||
var str = _Triple_JSON
|
||||
var r1 = NewHaltReader(str, testHalts())
|
||||
var r2 = NewHaltReader(str, testHalts())
|
||||
var v1 map[string]interface{}
|
||||
var v2 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
var d2 = decoder.NewStreamDecoder(r2)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
err1 := d1.Decode(&v1)
|
||||
err2 := d2.Decode(&v2)
|
||||
assert.Equal(t, err1, err2)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es4 := d1.Decode(&v1)
|
||||
ee4 := d2.Decode(&v2)
|
||||
assert.Equal(t, es4, ee4)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es2 := d1.Decode(&v1)
|
||||
ee2 := d2.Decode(&v2)
|
||||
assert.Equal(t, es2, ee2)
|
||||
assert.Equal(t, v1, v2)
|
||||
// assert.Equal(t, d1.InputOffset(), d2.InputOffset())
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
es5 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es5)
|
||||
ee5 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee5)
|
||||
}
|
||||
|
||||
func TestMore(t *testing.T) {
|
||||
var str = _Triple_JSON
|
||||
var r2 = NewHaltReader(str, testHalts())
|
||||
var v2 map[string]interface{}
|
||||
var d2 = decoder.NewStreamDecoder(r2)
|
||||
var r1 = NewHaltReader(str, testHalts())
|
||||
var v1 map[string]interface{}
|
||||
var d1 = jsoniter.NewDecoder(r1)
|
||||
require.Nil(t, d1.Decode(&v1))
|
||||
require.Nil(t, d2.Decode(&v2))
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es4 := d1.Decode(&v1)
|
||||
ee4 := d2.Decode(&v2)
|
||||
assert.Equal(t, es4, ee4)
|
||||
assert.Equal(t, v1, v2)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es2 := d1.Decode(&v1)
|
||||
ee2 := d2.Decode(&v2)
|
||||
assert.Equal(t, es2, ee2)
|
||||
assert.Equal(t, v1, v2)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es3 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es3)
|
||||
ee3 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee3)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
|
||||
es5 := d1.Decode(&v1)
|
||||
assert.NotNil(t, es5)
|
||||
ee5 := d2.Decode(&v2)
|
||||
assert.NotNil(t, ee5)
|
||||
require.Equal(t, d1.More(), d2.More())
|
||||
}
|
||||
|
|
@ -82,11 +82,18 @@ func fuzzMain(t *testing.T, data []byte) {
|
|||
jout, jerr := json.Marshal(jv)
|
||||
require.NoError(t, serr, "error in sonic marshal %v", reflect.TypeOf(jv))
|
||||
require.NoError(t, jerr, "error in json marshal %v", reflect.TypeOf(jv))
|
||||
// not comparing here because sonic marshal is different from encoding/json, as:
|
||||
// case 1: 1.23e2 -> `1.23e2` in sonic, but 1.23e2 -> `1.23e+2` in encoding/json
|
||||
// case 2: "\b" -> `\\b` in sonic, but `\u0008` in encoding/json
|
||||
// require.Equal(t, sout, jout, "different in sonic marshal %v", reflect.TypeOf(jv))
|
||||
var _, _ = sout, jout
|
||||
|
||||
{
|
||||
sv, jv := typ(), typ()
|
||||
serr := sonic.Unmarshal(sout, sv)
|
||||
jerr := json.Unmarshal(jout, jv)
|
||||
require.Equalf(t, serr != nil, jerr != nil, "different error in sonic unmarshal again %v", reflect.TypeOf(jv))
|
||||
if jerr != nil {
|
||||
return
|
||||
}
|
||||
require.Equal(t, sv, jv, "different result in sonic unmarshal again %v", reflect.TypeOf(jv))
|
||||
}
|
||||
|
||||
if m, ok := sv.(*map[string]interface{}); ok {
|
||||
fuzzDynamicStruct(t, jout, *m)
|
||||
fuzzASTGetFromObject(t, jout, *m)
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -5,12 +5,8 @@ go 1.15
|
|||
require (
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/goccy/go-json v0.9.4
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/klauspost/cpuid/v2 v2.0.9
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/tidwall/gjson v1.13.0
|
||||
github.com/tidwall/sjson v1.2.4
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670
|
||||
)
|
||||
|
|
|
|||
19
go.sum
19
go.sum
|
|
@ -3,32 +3,13 @@ github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/goccy/go-json v0.9.4 h1:L8MLKG2mvVXiQu07qB6hmfqeSYQdOnqPot2GhsIwIaI=
|
||||
github.com/goccy/go-json v0.9.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.13.0 h1:3TFY9yxOQShrvmjdM76K+jc66zJeT6D3/VFFYCGQf7M=
|
||||
github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc=
|
||||
github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
|
||||
|
|
|
|||
1
go.work
1
go.work
|
|
@ -4,4 +4,5 @@ use (
|
|||
.
|
||||
./generic_test
|
||||
./fuzz
|
||||
./external_jsonlib_test
|
||||
)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import (
|
|||
var (
|
||||
HasAVX = cpuid.CPU.Has(cpuid.AVX)
|
||||
HasAVX2 = cpuid.CPU.Has(cpuid.AVX2)
|
||||
HasSSE4 = cpuid.CPU.Has(cpuid.SSE4)
|
||||
HasSSE = cpuid.CPU.Has(cpuid.SSE)
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import (
|
|||
`math`
|
||||
`strconv`
|
||||
`testing`
|
||||
`math/rand`
|
||||
`encoding/json`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
|
@ -33,52 +35,106 @@ func TestFastFloat_Encode(t *testing.T) {
|
|||
assert.Equal(t, "12340000000" , string(buf[:__f64toa(&buf[0], 1234e7)]))
|
||||
assert.Equal(t, "12.34" , string(buf[:__f64toa(&buf[0], 1234e-2)]))
|
||||
assert.Equal(t, "0.001234" , string(buf[:__f64toa(&buf[0], 1234e-6)]))
|
||||
assert.Equal(t, "1e30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1e+30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e+33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e+308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1.234e-317" , string(buf[:__f64toa(&buf[0], 1234e-320)]))
|
||||
assert.Equal(t, "1.7976931348623157e308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "1.7976931348623157e+308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "-12340000000" , string(buf[:__f64toa(&buf[0], -1234e7)]))
|
||||
assert.Equal(t, "-12.34" , string(buf[:__f64toa(&buf[0], -1234e-2)]))
|
||||
assert.Equal(t, "-0.001234" , string(buf[:__f64toa(&buf[0], -1234e-6)]))
|
||||
assert.Equal(t, "-1e30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1e+30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e+33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e+308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1.234e-317" , string(buf[:__f64toa(&buf[0], -1234e-320)]))
|
||||
assert.Equal(t, "-2.2250738585072014e-308" , string(buf[:__f64toa(&buf[0], -2.2250738585072014e-308)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_Encode(b *testing.B) {
|
||||
val := -2.2250738585072014e-308
|
||||
benchmarks := []struct {
|
||||
func TestFastFloat_Random(t *testing.T) {
|
||||
var buf [64]byte
|
||||
N := 10000
|
||||
for i := 0; i < N; i++ {
|
||||
b64 := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
|
||||
f64 := math.Float64frombits(b64)
|
||||
|
||||
jout, jerr := json.Marshal(f64)
|
||||
n := __f64toa(&buf[0], f64)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
|
||||
f32 := math.Float32frombits(rand.Uint32())
|
||||
jout, jerr = json.Marshal(f32)
|
||||
n = __f32toa(&buf[0], f32)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseFloat64(b *testing.B) {
|
||||
var f64toaBenches = []struct {
|
||||
name string
|
||||
float float64
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Decimal", 33909},
|
||||
{"Float", 339.7784},
|
||||
{"Exp", -5.09e75},
|
||||
{"NegExp", -5.11e-95},
|
||||
{"LongExp", 1.234567890123456e-78},
|
||||
{"Big", 123456789123456789123456789},
|
||||
|
||||
}
|
||||
for _, c := range f64toaBenches {
|
||||
f64bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
for _, bm := range f64bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_EncodeZero(b *testing.B) {
|
||||
val := float64(0)
|
||||
benchmarks := []struct {
|
||||
func BenchmarkParseFloat32(b *testing.B) {
|
||||
var f32toaBenches = []struct {
|
||||
name string
|
||||
float float32
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Integer", 33909},
|
||||
{"ExactFraction", 3.375},
|
||||
{"Point", 339.7784},
|
||||
{"Exp", -5.09e25},
|
||||
{"NegExp", -5.11e-25},
|
||||
{"Shortest", 1.234567e-8},
|
||||
}
|
||||
for _, c := range f32toaBenches {
|
||||
bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
name: "StdLib32",
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
name: "FastFloat32",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f32toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
for _, bm := range bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package avx
|
|||
import (
|
||||
`strconv`
|
||||
`testing`
|
||||
`fmt`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
|
@ -96,16 +97,16 @@ func TestFastInt_UintToString(t *testing.T) {
|
|||
assert.Equal(t, "18446744073709551615" , string(buf[:__u64toa(&buf[0], 18446744073709551615)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], int64(i), 10) }},
|
||||
}, {
|
||||
name: "StdLib-Negative",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], -int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], -int64(i), 10) }},
|
||||
}, {
|
||||
name: "FastInt-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __i64toa(&buf[0], int64(i)) }},
|
||||
|
|
@ -116,20 +117,37 @@ func BenchmarkFastInt_IntToString(b *testing.B) {
|
|||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
type utoaBench struct {
|
||||
name string
|
||||
num uint64
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
maxUint := "18446744073709551615"
|
||||
benchs := make([]utoaBench, len(maxUint) + 1)
|
||||
benchs[0].name = "Zero"
|
||||
benchs[0].num = 0
|
||||
for i := 1; i <= len(maxUint); i++ {
|
||||
benchs[i].name = strconv.FormatInt(int64(i), 10) + "-Digs"
|
||||
benchs[i].num, _ = strconv.ParseUint(string(maxUint[:i]), 10, 64)
|
||||
}
|
||||
|
||||
for _, t := range(benchs) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:], uint64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:0], t.num, 10) }},
|
||||
}, {
|
||||
name: "FastInt",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], uint64(i)) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], t.num) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
name := fmt.Sprintf("%s_%s", bm.name, t.name)
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ func __f64toa(out *byte, val float64) (ret int)
|
|||
//go:nosplit
|
||||
//go:noescape
|
||||
//goland:noinspection GoUnusedParameter
|
||||
func __lzero(p unsafe.Pointer, n int) (ret int)
|
||||
func __f32toa(out *byte, val float32) (ret int)
|
||||
|
||||
//go:nosplit
|
||||
//go:noescape
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -20,6 +20,7 @@ package avx
|
|||
|
||||
var (
|
||||
S_f64toa = _subr__f64toa
|
||||
S_f32toa = _subr__f32toa
|
||||
S_i64toa = _subr__i64toa
|
||||
S_u64toa = _subr__u64toa
|
||||
S_lspace = _subr__lspace
|
||||
|
|
|
|||
|
|
@ -9,32 +9,32 @@ package avx
|
|||
func __native_entry__() uintptr
|
||||
|
||||
var (
|
||||
_subr__f64toa = __native_entry__() + 704
|
||||
_subr__html_escape = __native_entry__() + 9920
|
||||
_subr__i64toa = __native_entry__() + 3616
|
||||
_subr__lspace = __native_entry__() + 320
|
||||
_subr__lzero = __native_entry__() + 16
|
||||
_subr__quote = __native_entry__() + 4992
|
||||
_subr__skip_array = __native_entry__() + 22304
|
||||
_subr__skip_number = __native_entry__() + 23776
|
||||
_subr__skip_object = __native_entry__() + 22352
|
||||
_subr__skip_one = __native_entry__() + 20432
|
||||
_subr__u64toa = __native_entry__() + 3728
|
||||
_subr__unquote = __native_entry__() + 6736
|
||||
_subr__validate_one = __native_entry__() + 23920
|
||||
_subr__value = __native_entry__() + 13168
|
||||
_subr__vnumber = __native_entry__() + 18176
|
||||
_subr__vsigned = __native_entry__() + 19728
|
||||
_subr__vstring = __native_entry__() + 15248
|
||||
_subr__vunsigned = __native_entry__() + 20080
|
||||
_subr__f32toa = __native_entry__() + 24592
|
||||
_subr__f64toa = __native_entry__() + 496
|
||||
_subr__html_escape = __native_entry__() + 10480
|
||||
_subr__i64toa = __native_entry__() + 4176
|
||||
_subr__lspace = __native_entry__() + 80
|
||||
_subr__quote = __native_entry__() + 5552
|
||||
_subr__skip_array = __native_entry__() + 22864
|
||||
_subr__skip_number = __native_entry__() + 24336
|
||||
_subr__skip_object = __native_entry__() + 22912
|
||||
_subr__skip_one = __native_entry__() + 20992
|
||||
_subr__u64toa = __native_entry__() + 4288
|
||||
_subr__unquote = __native_entry__() + 7296
|
||||
_subr__validate_one = __native_entry__() + 24480
|
||||
_subr__value = __native_entry__() + 13728
|
||||
_subr__vnumber = __native_entry__() + 18736
|
||||
_subr__vsigned = __native_entry__() + 20288
|
||||
_subr__vstring = __native_entry__() + 15808
|
||||
_subr__vunsigned = __native_entry__() + 20640
|
||||
)
|
||||
|
||||
const (
|
||||
_stack__f64toa = 128
|
||||
_stack__f32toa = 64
|
||||
_stack__f64toa = 80
|
||||
_stack__html_escape = 64
|
||||
_stack__i64toa = 16
|
||||
_stack__lspace = 8
|
||||
_stack__lzero = 8
|
||||
_stack__quote = 80
|
||||
_stack__skip_array = 128
|
||||
_stack__skip_number = 72
|
||||
|
|
@ -51,11 +51,11 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
_ = _subr__f32toa
|
||||
_ = _subr__f64toa
|
||||
_ = _subr__html_escape
|
||||
_ = _subr__i64toa
|
||||
_ = _subr__lspace
|
||||
_ = _subr__lzero
|
||||
_ = _subr__quote
|
||||
_ = _subr__skip_array
|
||||
_ = _subr__skip_number
|
||||
|
|
@ -72,11 +72,11 @@ var (
|
|||
)
|
||||
|
||||
const (
|
||||
_ = _stack__f32toa
|
||||
_ = _stack__f64toa
|
||||
_ = _stack__html_escape
|
||||
_ = _stack__i64toa
|
||||
_ = _stack__lspace
|
||||
_ = _stack__lzero
|
||||
_ = _stack__quote
|
||||
_ = _stack__skip_array
|
||||
_ = _stack__skip_number
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import (
|
|||
`math`
|
||||
`strconv`
|
||||
`testing`
|
||||
`math/rand`
|
||||
`encoding/json`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
|
@ -33,52 +35,106 @@ func TestFastFloat_Encode(t *testing.T) {
|
|||
assert.Equal(t, "12340000000" , string(buf[:__f64toa(&buf[0], 1234e7)]))
|
||||
assert.Equal(t, "12.34" , string(buf[:__f64toa(&buf[0], 1234e-2)]))
|
||||
assert.Equal(t, "0.001234" , string(buf[:__f64toa(&buf[0], 1234e-6)]))
|
||||
assert.Equal(t, "1e30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1e+30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e+33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e+308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1.234e-317" , string(buf[:__f64toa(&buf[0], 1234e-320)]))
|
||||
assert.Equal(t, "1.7976931348623157e308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "1.7976931348623157e+308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "-12340000000" , string(buf[:__f64toa(&buf[0], -1234e7)]))
|
||||
assert.Equal(t, "-12.34" , string(buf[:__f64toa(&buf[0], -1234e-2)]))
|
||||
assert.Equal(t, "-0.001234" , string(buf[:__f64toa(&buf[0], -1234e-6)]))
|
||||
assert.Equal(t, "-1e30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1e+30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e+33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e+308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1.234e-317" , string(buf[:__f64toa(&buf[0], -1234e-320)]))
|
||||
assert.Equal(t, "-2.2250738585072014e-308" , string(buf[:__f64toa(&buf[0], -2.2250738585072014e-308)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_Encode(b *testing.B) {
|
||||
val := -2.2250738585072014e-308
|
||||
benchmarks := []struct {
|
||||
func TestFastFloat_Random(t *testing.T) {
|
||||
var buf [64]byte
|
||||
N := 10000
|
||||
for i := 0; i < N; i++ {
|
||||
b64 := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
|
||||
f64 := math.Float64frombits(b64)
|
||||
|
||||
jout, jerr := json.Marshal(f64)
|
||||
n := __f64toa(&buf[0], f64)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
|
||||
f32 := math.Float32frombits(rand.Uint32())
|
||||
jout, jerr = json.Marshal(f32)
|
||||
n = __f32toa(&buf[0], f32)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseFloat64(b *testing.B) {
|
||||
var f64toaBenches = []struct {
|
||||
name string
|
||||
float float64
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Decimal", 33909},
|
||||
{"Float", 339.7784},
|
||||
{"Exp", -5.09e75},
|
||||
{"NegExp", -5.11e-95},
|
||||
{"LongExp", 1.234567890123456e-78},
|
||||
{"Big", 123456789123456789123456789},
|
||||
|
||||
}
|
||||
for _, c := range f64toaBenches {
|
||||
f64bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
for _, bm := range f64bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_EncodeZero(b *testing.B) {
|
||||
val := float64(0)
|
||||
benchmarks := []struct {
|
||||
func BenchmarkParseFloat32(b *testing.B) {
|
||||
var f32toaBenches = []struct {
|
||||
name string
|
||||
float float32
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Integer", 33909},
|
||||
{"ExactFraction", 3.375},
|
||||
{"Point", 339.7784},
|
||||
{"Exp", -5.09e25},
|
||||
{"NegExp", -5.11e-25},
|
||||
{"Shortest", 1.234567e-8},
|
||||
}
|
||||
for _, c := range f32toaBenches {
|
||||
bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
name: "StdLib32",
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
name: "FastFloat32",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f32toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
for _, bm := range bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package avx2
|
|||
import (
|
||||
`strconv`
|
||||
`testing`
|
||||
`fmt`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
|
@ -96,16 +97,16 @@ func TestFastInt_UintToString(t *testing.T) {
|
|||
assert.Equal(t, "18446744073709551615" , string(buf[:__u64toa(&buf[0], 18446744073709551615)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], int64(i), 10) }},
|
||||
}, {
|
||||
name: "StdLib-Negative",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], -int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], -int64(i), 10) }},
|
||||
}, {
|
||||
name: "FastInt-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __i64toa(&buf[0], int64(i)) }},
|
||||
|
|
@ -116,20 +117,37 @@ func BenchmarkFastInt_IntToString(b *testing.B) {
|
|||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
type utoaBench struct {
|
||||
name string
|
||||
num uint64
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
maxUint := "18446744073709551615"
|
||||
benchs := make([]utoaBench, len(maxUint) + 1)
|
||||
benchs[0].name = "Zero"
|
||||
benchs[0].num = 0
|
||||
for i := 1; i <= len(maxUint); i++ {
|
||||
benchs[i].name = strconv.FormatInt(int64(i), 10) + "-Digs"
|
||||
benchs[i].num, _ = strconv.ParseUint(string(maxUint[:i]), 10, 64)
|
||||
}
|
||||
|
||||
for _, t := range(benchs) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:], uint64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:0], t.num, 10) }},
|
||||
}, {
|
||||
name: "FastInt",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], uint64(i)) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], t.num) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
name := fmt.Sprintf("%s_%s", bm.name, t.name)
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ func __f64toa(out *byte, val float64) (ret int)
|
|||
//go:nosplit
|
||||
//go:noescape
|
||||
//goland:noinspection GoUnusedParameter
|
||||
func __lzero(p unsafe.Pointer, n int) (ret int)
|
||||
func __f32toa(out *byte, val float32) (ret int)
|
||||
|
||||
//go:nosplit
|
||||
//go:noescape
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -20,6 +20,7 @@ package avx2
|
|||
|
||||
var (
|
||||
S_f64toa = _subr__f64toa
|
||||
S_f32toa = _subr__f32toa
|
||||
S_i64toa = _subr__i64toa
|
||||
S_u64toa = _subr__u64toa
|
||||
S_lspace = _subr__lspace
|
||||
|
|
|
|||
|
|
@ -9,32 +9,32 @@ package avx2
|
|||
func __native_entry__() uintptr
|
||||
|
||||
var (
|
||||
_subr__f64toa = __native_entry__() + 960
|
||||
_subr__html_escape = __native_entry__() + 11776
|
||||
_subr__i64toa = __native_entry__() + 3872
|
||||
_subr__lspace = __native_entry__() + 448
|
||||
_subr__lzero = __native_entry__() + 16
|
||||
_subr__quote = __native_entry__() + 5360
|
||||
_subr__skip_array = __native_entry__() + 25568
|
||||
_subr__skip_number = __native_entry__() + 27664
|
||||
_subr__skip_object = __native_entry__() + 25616
|
||||
_subr__skip_one = __native_entry__() + 23664
|
||||
_subr__u64toa = __native_entry__() + 3984
|
||||
_subr__unquote = __native_entry__() + 8304
|
||||
_subr__validate_one = __native_entry__() + 27808
|
||||
_subr__value = __native_entry__() + 16352
|
||||
_subr__vnumber = __native_entry__() + 21408
|
||||
_subr__vsigned = __native_entry__() + 22960
|
||||
_subr__vstring = __native_entry__() + 18736
|
||||
_subr__vunsigned = __native_entry__() + 23312
|
||||
_subr__f32toa = __native_entry__() + 28464
|
||||
_subr__f64toa = __native_entry__() + 752
|
||||
_subr__html_escape = __native_entry__() + 12320
|
||||
_subr__i64toa = __native_entry__() + 4432
|
||||
_subr__lspace = __native_entry__() + 224
|
||||
_subr__quote = __native_entry__() + 5904
|
||||
_subr__skip_array = __native_entry__() + 26112
|
||||
_subr__skip_number = __native_entry__() + 28208
|
||||
_subr__skip_object = __native_entry__() + 26160
|
||||
_subr__skip_one = __native_entry__() + 24208
|
||||
_subr__u64toa = __native_entry__() + 4544
|
||||
_subr__unquote = __native_entry__() + 8848
|
||||
_subr__validate_one = __native_entry__() + 28352
|
||||
_subr__value = __native_entry__() + 16896
|
||||
_subr__vnumber = __native_entry__() + 21952
|
||||
_subr__vsigned = __native_entry__() + 23504
|
||||
_subr__vstring = __native_entry__() + 19280
|
||||
_subr__vunsigned = __native_entry__() + 23856
|
||||
)
|
||||
|
||||
const (
|
||||
_stack__f64toa = 128
|
||||
_stack__f32toa = 64
|
||||
_stack__f64toa = 80
|
||||
_stack__html_escape = 72
|
||||
_stack__i64toa = 16
|
||||
_stack__lspace = 8
|
||||
_stack__lzero = 8
|
||||
_stack__quote = 72
|
||||
_stack__skip_array = 136
|
||||
_stack__skip_number = 80
|
||||
|
|
@ -51,11 +51,11 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
_ = _subr__f32toa
|
||||
_ = _subr__f64toa
|
||||
_ = _subr__html_escape
|
||||
_ = _subr__i64toa
|
||||
_ = _subr__lspace
|
||||
_ = _subr__lzero
|
||||
_ = _subr__quote
|
||||
_ = _subr__skip_array
|
||||
_ = _subr__skip_number
|
||||
|
|
@ -72,11 +72,11 @@ var (
|
|||
)
|
||||
|
||||
const (
|
||||
_ = _stack__f32toa
|
||||
_ = _stack__f64toa
|
||||
_ = _stack__html_escape
|
||||
_ = _stack__i64toa
|
||||
_ = _stack__lspace
|
||||
_ = _stack__lzero
|
||||
_ = _stack__quote
|
||||
_ = _stack__skip_array
|
||||
_ = _stack__skip_number
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
`github.com/bytedance/sonic/internal/cpu`
|
||||
`github.com/bytedance/sonic/internal/native/avx`
|
||||
`github.com/bytedance/sonic/internal/native/avx2`
|
||||
`github.com/bytedance/sonic/internal/native/sse4`
|
||||
`github.com/bytedance/sonic/internal/native/sse`
|
||||
`github.com/bytedance/sonic/internal/native/types`
|
||||
)
|
||||
|
||||
|
|
@ -30,6 +30,7 @@ const MaxFrameSize uintptr = 400
|
|||
|
||||
var (
|
||||
S_f64toa uintptr
|
||||
S_f32toa uintptr
|
||||
S_i64toa uintptr
|
||||
S_u64toa uintptr
|
||||
S_lspace uintptr
|
||||
|
|
@ -97,6 +98,7 @@ func U64toa(out *byte, val uint64) (ret int)
|
|||
|
||||
func useAVX() {
|
||||
S_f64toa = avx.S_f64toa
|
||||
S_f32toa = avx.S_f32toa
|
||||
S_i64toa = avx.S_i64toa
|
||||
S_u64toa = avx.S_u64toa
|
||||
S_lspace = avx.S_lspace
|
||||
|
|
@ -115,6 +117,7 @@ func useAVX() {
|
|||
|
||||
func useAVX2() {
|
||||
S_f64toa = avx2.S_f64toa
|
||||
S_f32toa = avx2.S_f32toa
|
||||
S_i64toa = avx2.S_i64toa
|
||||
S_u64toa = avx2.S_u64toa
|
||||
S_lspace = avx2.S_lspace
|
||||
|
|
@ -131,22 +134,23 @@ func useAVX2() {
|
|||
S_skip_number = avx2.S_skip_number
|
||||
}
|
||||
|
||||
func useSSE4() {
|
||||
S_f64toa = sse4.S_f64toa
|
||||
S_i64toa = sse4.S_i64toa
|
||||
S_u64toa = sse4.S_u64toa
|
||||
S_lspace = sse4.S_lspace
|
||||
S_quote = sse4.S_quote
|
||||
S_unquote = sse4.S_unquote
|
||||
S_value = sse4.S_value
|
||||
S_vstring = sse4.S_vstring
|
||||
S_vnumber = sse4.S_vnumber
|
||||
S_vsigned = sse4.S_vsigned
|
||||
S_vunsigned = sse4.S_vunsigned
|
||||
S_skip_one = sse4.S_skip_one
|
||||
S_skip_array = sse4.S_skip_array
|
||||
S_skip_object = sse4.S_skip_object
|
||||
S_skip_number = sse4.S_skip_number
|
||||
func useSSE() {
|
||||
S_f64toa = sse.S_f64toa
|
||||
S_f32toa = sse.S_f32toa
|
||||
S_i64toa = sse.S_i64toa
|
||||
S_u64toa = sse.S_u64toa
|
||||
S_lspace = sse.S_lspace
|
||||
S_quote = sse.S_quote
|
||||
S_unquote = sse.S_unquote
|
||||
S_value = sse.S_value
|
||||
S_vstring = sse.S_vstring
|
||||
S_vnumber = sse.S_vnumber
|
||||
S_vsigned = sse.S_vsigned
|
||||
S_vunsigned = sse.S_vunsigned
|
||||
S_skip_one = sse.S_skip_one
|
||||
S_skip_array = sse.S_skip_array
|
||||
S_skip_object = sse.S_skip_object
|
||||
S_skip_number = sse.S_skip_number
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -154,8 +158,8 @@ func init() {
|
|||
useAVX2()
|
||||
} else if cpu.HasAVX {
|
||||
useAVX()
|
||||
} else if cpu.HasSSE4 {
|
||||
useSSE4()
|
||||
} else if cpu.HasSSE {
|
||||
useSSE()
|
||||
} else {
|
||||
panic("Unsupported CPU, maybe it's too old to run Sonic.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ TEXT ·Quote(SB), NOSPLIT, $0 - 48
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__quote(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__quote(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__quote(SB)
|
||||
|
||||
TEXT ·Unquote(SB), NOSPLIT, $0 - 48
|
||||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX2(SB), $0
|
||||
|
|
@ -34,7 +34,7 @@ TEXT ·Unquote(SB), NOSPLIT, $0 - 48
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__unquote(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__unquote(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__unquote(SB)
|
||||
|
||||
TEXT ·HTMLEscape(SB), NOSPLIT, $0 - 40
|
||||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX2(SB), $0
|
||||
|
|
@ -43,7 +43,7 @@ TEXT ·HTMLEscape(SB), NOSPLIT, $0 - 40
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__html_escape(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__html_escape(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__html_escape(SB)
|
||||
|
||||
|
||||
TEXT ·Value(SB), NOSPLIT, $0 - 48
|
||||
|
|
@ -53,7 +53,7 @@ TEXT ·Value(SB), NOSPLIT, $0 - 48
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__value(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__value(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__value(SB)
|
||||
|
||||
TEXT ·SkipOne(SB), NOSPLIT, $0 - 40
|
||||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX2(SB), $0
|
||||
|
|
@ -62,7 +62,7 @@ TEXT ·SkipOne(SB), NOSPLIT, $0 - 40
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__skip_one(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__skip_one(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__skip_one(SB)
|
||||
|
||||
TEXT ·ValidateOne(SB), NOSPLIT, $0 - 32
|
||||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX2(SB), $0
|
||||
|
|
@ -71,7 +71,7 @@ TEXT ·ValidateOne(SB), NOSPLIT, $0 - 32
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__validate_one(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__validate_one(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__validate_one(SB)
|
||||
|
||||
TEXT ·I64toa(SB), NOSPLIT, $0 - 32
|
||||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX2(SB), $0
|
||||
|
|
@ -80,7 +80,7 @@ TEXT ·I64toa(SB), NOSPLIT, $0 - 32
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__i64toa(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__i64toa(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__i64toa(SB)
|
||||
|
||||
TEXT ·U64toa(SB), NOSPLIT, $0 - 32
|
||||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX2(SB), $0
|
||||
|
|
@ -89,5 +89,5 @@ TEXT ·U64toa(SB), NOSPLIT, $0 - 32
|
|||
CMPB github·com∕bytedance∕sonic∕internal∕cpu·HasAVX(SB), $0
|
||||
JE 2(PC)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕avx·__u64toa(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse4·__u64toa(SB)
|
||||
JMP github·com∕bytedance∕sonic∕internal∕native∕sse·__u64toa(SB)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
`math`
|
||||
`strconv`
|
||||
`testing`
|
||||
`math/rand`
|
||||
`encoding/json`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
|
@ -31,52 +33,106 @@ func TestFastFloat_Encode(t *testing.T) {
|
|||
assert.Equal(t, "12340000000" , string(buf[:__f64toa(&buf[0], 1234e7)]))
|
||||
assert.Equal(t, "12.34" , string(buf[:__f64toa(&buf[0], 1234e-2)]))
|
||||
assert.Equal(t, "0.001234" , string(buf[:__f64toa(&buf[0], 1234e-6)]))
|
||||
assert.Equal(t, "1e30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1e+30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e+33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e+308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1.234e-317" , string(buf[:__f64toa(&buf[0], 1234e-320)]))
|
||||
assert.Equal(t, "1.7976931348623157e308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "1.7976931348623157e+308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "-12340000000" , string(buf[:__f64toa(&buf[0], -1234e7)]))
|
||||
assert.Equal(t, "-12.34" , string(buf[:__f64toa(&buf[0], -1234e-2)]))
|
||||
assert.Equal(t, "-0.001234" , string(buf[:__f64toa(&buf[0], -1234e-6)]))
|
||||
assert.Equal(t, "-1e30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1e+30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e+33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e+308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1.234e-317" , string(buf[:__f64toa(&buf[0], -1234e-320)]))
|
||||
assert.Equal(t, "-2.2250738585072014e-308" , string(buf[:__f64toa(&buf[0], -2.2250738585072014e-308)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_Encode(b *testing.B) {
|
||||
val := -2.2250738585072014e-308
|
||||
benchmarks := []struct {
|
||||
func TestFastFloat_Random(t *testing.T) {
|
||||
var buf [64]byte
|
||||
N := 10000
|
||||
for i := 0; i < N; i++ {
|
||||
b64 := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
|
||||
f64 := math.Float64frombits(b64)
|
||||
|
||||
jout, jerr := json.Marshal(f64)
|
||||
n := __f64toa(&buf[0], f64)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
|
||||
f32 := math.Float32frombits(rand.Uint32())
|
||||
jout, jerr = json.Marshal(f32)
|
||||
n = __f32toa(&buf[0], f32)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseFloat64(b *testing.B) {
|
||||
var f64toaBenches = []struct {
|
||||
name string
|
||||
float float64
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Decimal", 33909},
|
||||
{"Float", 339.7784},
|
||||
{"Exp", -5.09e75},
|
||||
{"NegExp", -5.11e-95},
|
||||
{"LongExp", 1.234567890123456e-78},
|
||||
{"Big", 123456789123456789123456789},
|
||||
|
||||
}
|
||||
for _, c := range f64toaBenches {
|
||||
f64bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
for _, bm := range f64bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_EncodeZero(b *testing.B) {
|
||||
val := float64(0)
|
||||
benchmarks := []struct {
|
||||
func BenchmarkParseFloat32(b *testing.B) {
|
||||
var f32toaBenches = []struct {
|
||||
name string
|
||||
float float32
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Integer", 33909},
|
||||
{"ExactFraction", 3.375},
|
||||
{"Point", 339.7784},
|
||||
{"Exp", -5.09e25},
|
||||
{"NegExp", -5.11e-25},
|
||||
{"Shortest", 1.234567e-8},
|
||||
}
|
||||
for _, c := range f32toaBenches {
|
||||
bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
name: "StdLib32",
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
name: "FastFloat32",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f32toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
for _, bm := range bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package {{PACKAGE}}
|
|||
import (
|
||||
`strconv`
|
||||
`testing`
|
||||
`fmt`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
|
@ -94,16 +95,16 @@ func TestFastInt_UintToString(t *testing.T) {
|
|||
assert.Equal(t, "18446744073709551615" , string(buf[:__u64toa(&buf[0], 18446744073709551615)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], int64(i), 10) }},
|
||||
}, {
|
||||
name: "StdLib-Negative",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], -int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], -int64(i), 10) }},
|
||||
}, {
|
||||
name: "FastInt-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __i64toa(&buf[0], int64(i)) }},
|
||||
|
|
@ -114,20 +115,37 @@ func BenchmarkFastInt_IntToString(b *testing.B) {
|
|||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
type utoaBench struct {
|
||||
name string
|
||||
num uint64
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
maxUint := "18446744073709551615"
|
||||
benchs := make([]utoaBench, len(maxUint) + 1)
|
||||
benchs[0].name = "Zero"
|
||||
benchs[0].num = 0
|
||||
for i := 1; i <= len(maxUint); i++ {
|
||||
benchs[i].name = strconv.FormatInt(int64(i), 10) + "-Digs"
|
||||
benchs[i].num, _ = strconv.ParseUint(string(maxUint[:i]), 10, 64)
|
||||
}
|
||||
|
||||
for _, t := range(benchs) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:], uint64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:0], t.num, 10) }},
|
||||
}, {
|
||||
name: "FastInt",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], uint64(i)) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], t.num) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
name := fmt.Sprintf("%s_%s", bm.name, t.name)
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func __f64toa(out *byte, val float64) (ret int)
|
|||
//go:nosplit
|
||||
//go:noescape
|
||||
//goland:noinspection GoUnusedParameter
|
||||
func __lzero(p unsafe.Pointer, n int) (ret int)
|
||||
func __f32toa(out *byte, val float32) (ret int)
|
||||
|
||||
//go:nosplit
|
||||
//go:noescape
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package {{PACKAGE}}
|
|||
|
||||
var (
|
||||
S_f64toa = _subr__f64toa
|
||||
S_f32toa = _subr__f32toa
|
||||
S_i64toa = _subr__i64toa
|
||||
S_u64toa = _subr__u64toa
|
||||
S_lspace = _subr__lspace
|
||||
|
|
|
|||
140
internal/native/sse/fastfloat_amd64_test.go
Normal file
140
internal/native/sse/fastfloat_amd64_test.go
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
// Code generated by Makefile, DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sse
|
||||
|
||||
import (
|
||||
`math`
|
||||
`strconv`
|
||||
`testing`
|
||||
`math/rand`
|
||||
`encoding/json`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
||||
func TestFastFloat_Encode(t *testing.T) {
|
||||
var buf [64]byte
|
||||
assert.Equal(t, "0" , string(buf[:__f64toa(&buf[0], 0)]))
|
||||
assert.Equal(t, "-0" , string(buf[:__f64toa(&buf[0], math.Float64frombits(0x8000000000000000))]))
|
||||
assert.Equal(t, "12340000000" , string(buf[:__f64toa(&buf[0], 1234e7)]))
|
||||
assert.Equal(t, "12.34" , string(buf[:__f64toa(&buf[0], 1234e-2)]))
|
||||
assert.Equal(t, "0.001234" , string(buf[:__f64toa(&buf[0], 1234e-6)]))
|
||||
assert.Equal(t, "1e+30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e+33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e+308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1.234e-317" , string(buf[:__f64toa(&buf[0], 1234e-320)]))
|
||||
assert.Equal(t, "1.7976931348623157e+308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "-12340000000" , string(buf[:__f64toa(&buf[0], -1234e7)]))
|
||||
assert.Equal(t, "-12.34" , string(buf[:__f64toa(&buf[0], -1234e-2)]))
|
||||
assert.Equal(t, "-0.001234" , string(buf[:__f64toa(&buf[0], -1234e-6)]))
|
||||
assert.Equal(t, "-1e+30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e+33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e+308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1.234e-317" , string(buf[:__f64toa(&buf[0], -1234e-320)]))
|
||||
assert.Equal(t, "-2.2250738585072014e-308" , string(buf[:__f64toa(&buf[0], -2.2250738585072014e-308)]))
|
||||
}
|
||||
|
||||
func TestFastFloat_Random(t *testing.T) {
|
||||
var buf [64]byte
|
||||
N := 10000
|
||||
for i := 0; i < N; i++ {
|
||||
b64 := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
|
||||
f64 := math.Float64frombits(b64)
|
||||
|
||||
jout, jerr := json.Marshal(f64)
|
||||
n := __f64toa(&buf[0], f64)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
|
||||
f32 := math.Float32frombits(rand.Uint32())
|
||||
jout, jerr = json.Marshal(f32)
|
||||
n = __f32toa(&buf[0], f32)
|
||||
if jerr == nil {
|
||||
assert.Equal(t, jout, buf[:n])
|
||||
} else {
|
||||
assert.True(t, n == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseFloat64(b *testing.B) {
|
||||
var f64toaBenches = []struct {
|
||||
name string
|
||||
float float64
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Decimal", 33909},
|
||||
{"Float", 339.7784},
|
||||
{"Exp", -5.09e75},
|
||||
{"NegExp", -5.11e-95},
|
||||
{"LongExp", 1.234567890123456e-78},
|
||||
{"Big", 123456789123456789123456789},
|
||||
|
||||
}
|
||||
for _, c := range f64toaBenches {
|
||||
f64bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range f64bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParseFloat32(b *testing.B) {
|
||||
var f32toaBenches = []struct {
|
||||
name string
|
||||
float float32
|
||||
}{
|
||||
{"Zero", 0},
|
||||
{"Integer", 33909},
|
||||
{"ExactFraction", 3.375},
|
||||
{"Point", 339.7784},
|
||||
{"Exp", -5.09e25},
|
||||
{"NegExp", -5.11e-25},
|
||||
{"Shortest", 1.234567e-8},
|
||||
}
|
||||
for _, c := range f32toaBenches {
|
||||
bench := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib32",
|
||||
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) }},
|
||||
}, {
|
||||
name: "FastFloat32",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f32toa(&buf[0], c.float) }},
|
||||
}}
|
||||
for _, bm := range bench {
|
||||
name := bm.name + "_" + c.name
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,11 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sse4
|
||||
package sse
|
||||
|
||||
import (
|
||||
`strconv`
|
||||
`testing`
|
||||
`fmt`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
|
@ -96,16 +97,16 @@ func TestFastInt_UintToString(t *testing.T) {
|
|||
assert.Equal(t, "18446744073709551615" , string(buf[:__u64toa(&buf[0], 18446744073709551615)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
func BenchmarkFastInt_IntToString(b *testing.B) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], int64(i), 10) }},
|
||||
}, {
|
||||
name: "StdLib-Negative",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:], -int64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendInt(buf[:0], -int64(i), 10) }},
|
||||
}, {
|
||||
name: "FastInt-Positive",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __i64toa(&buf[0], int64(i)) }},
|
||||
|
|
@ -116,20 +117,37 @@ func BenchmarkFastInt_IntToString(b *testing.B) {
|
|||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
type utoaBench struct {
|
||||
name string
|
||||
num uint64
|
||||
}
|
||||
|
||||
func BenchmarkFastInt_UintToString(b *testing.B) {
|
||||
maxUint := "18446744073709551615"
|
||||
benchs := make([]utoaBench, len(maxUint) + 1)
|
||||
benchs[0].name = "Zero"
|
||||
benchs[0].num = 0
|
||||
for i := 1; i <= len(maxUint); i++ {
|
||||
benchs[i].name = strconv.FormatInt(int64(i), 10) + "-Digs"
|
||||
benchs[i].num, _ = strconv.ParseUint(string(maxUint[:i]), 10, 64)
|
||||
}
|
||||
|
||||
for _, t := range(benchs) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:], uint64(i), 10) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { strconv.AppendUint(buf[:0], t.num, 10) }},
|
||||
}, {
|
||||
name: "FastInt",
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], uint64(i)) }},
|
||||
test: func(b *testing.B) { var buf [32]byte; for i := 0; i < b.N; i++ { __u64toa(&buf[0], t.num) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
name := fmt.Sprintf("%s_%s", bm.name, t.name)
|
||||
b.Run(name, bm.test)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sse4
|
||||
package sse
|
||||
|
||||
import (
|
||||
`unsafe`
|
||||
|
|
@ -42,7 +42,7 @@ func __f64toa(out *byte, val float64) (ret int)
|
|||
//go:nosplit
|
||||
//go:noescape
|
||||
//goland:noinspection GoUnusedParameter
|
||||
func __lzero(p unsafe.Pointer, n int) (ret int)
|
||||
func __f32toa(out *byte, val float32) (ret int)
|
||||
|
||||
//go:nosplit
|
||||
//go:noescape
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sse4
|
||||
package sse
|
||||
|
||||
import (
|
||||
`encoding/hex`
|
||||
|
|
@ -16,10 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sse4
|
||||
package sse
|
||||
|
||||
var (
|
||||
S_f64toa = _subr__f64toa
|
||||
S_f32toa = _subr__f32toa
|
||||
S_i64toa = _subr__i64toa
|
||||
S_u64toa = _subr__u64toa
|
||||
S_lspace = _subr__lspace
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// +build !noasm !appengine
|
||||
// Code generated by asm2asm, DO NOT EDIT.
|
||||
|
||||
package sse4
|
||||
package sse
|
||||
|
||||
//go:nosplit
|
||||
//go:noescape
|
||||
|
|
@ -9,32 +9,32 @@ package sse4
|
|||
func __native_entry__() uintptr
|
||||
|
||||
var (
|
||||
_subr__f64toa = __native_entry__() + 640
|
||||
_subr__html_escape = __native_entry__() + 9808
|
||||
_subr__i64toa = __native_entry__() + 3440
|
||||
_subr__lspace = __native_entry__() + 256
|
||||
_subr__lzero = __native_entry__() + 16
|
||||
_subr__quote = __native_entry__() + 4848
|
||||
_subr__skip_array = __native_entry__() + 22320
|
||||
_subr__skip_number = __native_entry__() + 23824
|
||||
_subr__skip_object = __native_entry__() + 22368
|
||||
_subr__skip_one = __native_entry__() + 20448
|
||||
_subr__u64toa = __native_entry__() + 3568
|
||||
_subr__unquote = __native_entry__() + 6624
|
||||
_subr__validate_one = __native_entry__() + 23968
|
||||
_subr__value = __native_entry__() + 13072
|
||||
_subr__vnumber = __native_entry__() + 18192
|
||||
_subr__vsigned = __native_entry__() + 19744
|
||||
_subr__vstring = __native_entry__() + 15152
|
||||
_subr__vunsigned = __native_entry__() + 20096
|
||||
_subr__f32toa = __native_entry__() + 24640
|
||||
_subr__f64toa = __native_entry__() + 464
|
||||
_subr__html_escape = __native_entry__() + 10416
|
||||
_subr__i64toa = __native_entry__() + 4048
|
||||
_subr__lspace = __native_entry__() + 80
|
||||
_subr__quote = __native_entry__() + 5456
|
||||
_subr__skip_array = __native_entry__() + 22928
|
||||
_subr__skip_number = __native_entry__() + 24432
|
||||
_subr__skip_object = __native_entry__() + 22976
|
||||
_subr__skip_one = __native_entry__() + 21056
|
||||
_subr__u64toa = __native_entry__() + 4176
|
||||
_subr__unquote = __native_entry__() + 7232
|
||||
_subr__validate_one = __native_entry__() + 24576
|
||||
_subr__value = __native_entry__() + 13680
|
||||
_subr__vnumber = __native_entry__() + 18800
|
||||
_subr__vsigned = __native_entry__() + 20352
|
||||
_subr__vstring = __native_entry__() + 15760
|
||||
_subr__vunsigned = __native_entry__() + 20704
|
||||
)
|
||||
|
||||
const (
|
||||
_stack__f64toa = 128
|
||||
_stack__f32toa = 64
|
||||
_stack__f64toa = 80
|
||||
_stack__html_escape = 64
|
||||
_stack__i64toa = 16
|
||||
_stack__lspace = 8
|
||||
_stack__lzero = 8
|
||||
_stack__quote = 80
|
||||
_stack__skip_array = 128
|
||||
_stack__skip_number = 72
|
||||
|
|
@ -51,11 +51,11 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
_ = _subr__f32toa
|
||||
_ = _subr__f64toa
|
||||
_ = _subr__html_escape
|
||||
_ = _subr__i64toa
|
||||
_ = _subr__lspace
|
||||
_ = _subr__lzero
|
||||
_ = _subr__quote
|
||||
_ = _subr__skip_array
|
||||
_ = _subr__skip_number
|
||||
|
|
@ -72,11 +72,11 @@ var (
|
|||
)
|
||||
|
||||
const (
|
||||
_ = _stack__f32toa
|
||||
_ = _stack__f64toa
|
||||
_ = _stack__html_escape
|
||||
_ = _stack__i64toa
|
||||
_ = _stack__lspace
|
||||
_ = _stack__lzero
|
||||
_ = _stack__quote
|
||||
_ = _stack__skip_array
|
||||
_ = _stack__skip_number
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
// Code generated by Makefile, DO NOT EDIT.
|
||||
|
||||
/*
|
||||
* Copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sse4
|
||||
|
||||
import (
|
||||
`math`
|
||||
`strconv`
|
||||
`testing`
|
||||
|
||||
`github.com/stretchr/testify/assert`
|
||||
)
|
||||
|
||||
func TestFastFloat_Encode(t *testing.T) {
|
||||
var buf [64]byte
|
||||
assert.Equal(t, "0" , string(buf[:__f64toa(&buf[0], 0)]))
|
||||
assert.Equal(t, "-0" , string(buf[:__f64toa(&buf[0], math.Float64frombits(0x8000000000000000))]))
|
||||
assert.Equal(t, "12340000000" , string(buf[:__f64toa(&buf[0], 1234e7)]))
|
||||
assert.Equal(t, "12.34" , string(buf[:__f64toa(&buf[0], 1234e-2)]))
|
||||
assert.Equal(t, "0.001234" , string(buf[:__f64toa(&buf[0], 1234e-6)]))
|
||||
assert.Equal(t, "1e30" , string(buf[:__f64toa(&buf[0], 1e30)]))
|
||||
assert.Equal(t, "1.234e33" , string(buf[:__f64toa(&buf[0], 1234e30)]))
|
||||
assert.Equal(t, "1.234e308" , string(buf[:__f64toa(&buf[0], 1234e305)]))
|
||||
assert.Equal(t, "1.234e-317" , string(buf[:__f64toa(&buf[0], 1234e-320)]))
|
||||
assert.Equal(t, "1.7976931348623157e308" , string(buf[:__f64toa(&buf[0], 1.7976931348623157e308)]))
|
||||
assert.Equal(t, "-12340000000" , string(buf[:__f64toa(&buf[0], -1234e7)]))
|
||||
assert.Equal(t, "-12.34" , string(buf[:__f64toa(&buf[0], -1234e-2)]))
|
||||
assert.Equal(t, "-0.001234" , string(buf[:__f64toa(&buf[0], -1234e-6)]))
|
||||
assert.Equal(t, "-1e30" , string(buf[:__f64toa(&buf[0], -1e30)]))
|
||||
assert.Equal(t, "-1.234e33" , string(buf[:__f64toa(&buf[0], -1234e30)]))
|
||||
assert.Equal(t, "-1.234e308" , string(buf[:__f64toa(&buf[0], -1234e305)]))
|
||||
assert.Equal(t, "-1.234e-317" , string(buf[:__f64toa(&buf[0], -1234e-320)]))
|
||||
assert.Equal(t, "-2.2250738585072014e-308" , string(buf[:__f64toa(&buf[0], -2.2250738585072014e-308)]))
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_Encode(b *testing.B) {
|
||||
val := -2.2250738585072014e-308
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFastFloat_EncodeZero(b *testing.B) {
|
||||
val := float64(0)
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
test func(*testing.B)
|
||||
}{{
|
||||
name: "StdLib",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { strconv.AppendFloat(buf[:], val, 'g', -1, 64) }},
|
||||
}, {
|
||||
name: "FastFloat",
|
||||
test: func(b *testing.B) { var buf [64]byte; for i := 0; i < b.N; i++ { __f64toa(&buf[0], val) }},
|
||||
}}
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, bm.test)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ var issue13ExpectedNonemptyOpt = `{
|
|||
"uint32": 32,
|
||||
"uint64": 64,
|
||||
"float32": 1,
|
||||
"float64": -2.34e64,
|
||||
"float64": -2.34e+64,
|
||||
"uintptr": 1,
|
||||
"string": "string",
|
||||
"array": [
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* Copyright 2022 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package issue_test
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* Copyright 2022 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package issue_test
|
||||
|
||||
import (
|
||||
|
|
|
|||
40
issue_test/issue273_test.go
Normal file
40
issue_test/issue273_test.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*
|
||||
* Copyright 2022 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package issue_test
|
||||
|
||||
import (
|
||||
`testing`
|
||||
|
||||
`encoding/json`
|
||||
`github.com/bytedance/sonic`
|
||||
`github.com/stretchr/testify/require`
|
||||
)
|
||||
|
||||
func TestMarshal_Float32To64(t *testing.T) {
|
||||
var f float32 = 0.1
|
||||
oe,ee := json.Marshal(f)
|
||||
os,es := sonic.Marshal(f)
|
||||
require.Equal(t, ee == nil, es == nil)
|
||||
require.Equal(t, string(oe), string(os))
|
||||
|
||||
var f2,f3 float64
|
||||
require.Nil(t, json.Unmarshal(oe, &f2))
|
||||
require.Nil(t, sonic.Unmarshal(os, &f3))
|
||||
require.Equal(t, f2, f3)
|
||||
}
|
||||
23
licenses/LICENSE-Drachennest
Normal file
23
licenses/LICENSE-Drachennest
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
452
native/f32toa.c
Normal file
452
native/f32toa.c
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
/* Copyright 2020 Alexander Bolz
|
||||
*
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer,
|
||||
* must be included in all copies of the Software, in whole or in part, and
|
||||
* all derivative works of the Software, unless such copies or derivative
|
||||
* works are solely in the form of machine-executable object code generated by
|
||||
* a source language processor.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this software
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* This file may have been modified by ByteDance authors. All ByteDance
|
||||
* Modifications are Copyright 2022 ByteDance Authors.
|
||||
*/
|
||||
|
||||
#include "native.h"
|
||||
#include "tab.h"
|
||||
#include "test/xassert.h"
|
||||
|
||||
#define F32_BITS 32
|
||||
#define F32_EXP_BITS 8
|
||||
#define F32_SIG_BITS 23
|
||||
#define F32_EXP_MASK 0x7F800000u // middle 8 bits
|
||||
#define F32_SIG_MASK 0x007FFFFFu // lower 23 bits
|
||||
#define F32_EXP_BIAS 127
|
||||
#define F32_INF_NAN_EXP 0xFF
|
||||
#define F32_HIDDEN_BIT 0x00800000u
|
||||
|
||||
typedef struct {
|
||||
uint32_t sig;
|
||||
int32_t exp;
|
||||
} f32_dec;
|
||||
|
||||
static inline unsigned ctz10_u32(const uint32_t v) {
|
||||
xassert(0 <= v && v < 1000000000u);
|
||||
if (v >= 100000) {
|
||||
if (v < 1000000) return 6;
|
||||
if (v < 10000000) return 7;
|
||||
if (v < 100000000) return 8;
|
||||
return 9;
|
||||
} else {
|
||||
if (v < 10) return 1;
|
||||
if (v < 100) return 2;
|
||||
if (v < 1000) return 3;
|
||||
if (v < 10000) return 4;
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
static inline char* format_significand_f32(uint32_t sig, char *out, int cnt) {
|
||||
char *r = out + cnt;
|
||||
int ctz = 0;
|
||||
|
||||
/* at most 9 digits here */
|
||||
if (sig >= 10000) {
|
||||
uint32_t c = sig - 10000 * (sig / 10000);
|
||||
sig /= 10000;
|
||||
if (c != 0) {
|
||||
uint32_t c0 = (c % 100) << 1;
|
||||
uint32_t c1 = (c / 100) << 1;
|
||||
copy_two_digs(r - 2, Digits + c0);
|
||||
copy_two_digs(r - 4, Digits + c1);
|
||||
} else {
|
||||
ctz = 4;
|
||||
}
|
||||
r -= 4;
|
||||
}
|
||||
|
||||
while (sig >= 100) {
|
||||
uint32_t c = (sig % 100) << 1;
|
||||
sig /= 100;
|
||||
copy_two_digs(r - 2, Digits + c);
|
||||
r -= 2;
|
||||
}
|
||||
|
||||
if (sig >= 10) {
|
||||
uint32_t c = sig << 1;
|
||||
copy_two_digs(out, Digits + c);
|
||||
} else {
|
||||
*out = (char) ('0' + sig);
|
||||
}
|
||||
|
||||
return out + cnt - ctz;
|
||||
}
|
||||
|
||||
static inline char* format_integer_u32(uint32_t sig, char *out, unsigned cnt) {
|
||||
char *r = out + cnt;
|
||||
|
||||
/* at most 9 digits here */
|
||||
if (sig >= 10000) {
|
||||
uint32_t c = sig - 10000 * (sig / 10000);
|
||||
sig /= 10000;
|
||||
uint32_t c0 = (c % 100) << 1;
|
||||
uint32_t c1 = (c / 100) << 1;
|
||||
copy_two_digs(r - 2, Digits + c0);
|
||||
copy_two_digs(r - 4, Digits + c1);
|
||||
r -= 4;
|
||||
}
|
||||
|
||||
while (sig >= 100) {
|
||||
uint32_t c = (sig % 100) << 1;
|
||||
sig /= 100;
|
||||
copy_two_digs(r - 2, Digits + c);
|
||||
r -= 2;
|
||||
}
|
||||
|
||||
if (sig >= 10) {
|
||||
uint32_t c = sig << 1;
|
||||
copy_two_digs(out, Digits + c);
|
||||
} else {
|
||||
*out = (char) ('0' + sig);
|
||||
}
|
||||
|
||||
return out + cnt;
|
||||
}
|
||||
|
||||
static inline char* format_exponent_f32(f32_dec v, char *out, int cnt) {
|
||||
char* p = out + 1;
|
||||
char* end = format_significand_f32(v.sig, p, cnt);
|
||||
while (*(end - 1) == '0') end--;
|
||||
|
||||
/* Print decimal point if needed */
|
||||
*out = *p;
|
||||
if (end - p > 1) {
|
||||
*p = '.';
|
||||
} else {
|
||||
end--;
|
||||
}
|
||||
|
||||
/* Print the exponent */
|
||||
*end++ = 'e';
|
||||
int32_t exp = v.exp + (int32_t) cnt - 1;
|
||||
if (exp < 0) {
|
||||
*end++ = '-';
|
||||
exp = -exp;
|
||||
} else {
|
||||
*end++ = '+';
|
||||
}
|
||||
|
||||
if (exp >= 100) {
|
||||
int32_t c = exp % 10;
|
||||
copy_two_digs(end, Digits + 2 * (exp / 10));
|
||||
end[2] = (char) ('0' + c);
|
||||
end += 3;
|
||||
} else if (exp >= 10) {
|
||||
copy_two_digs(end, Digits + 2 * exp);
|
||||
end += 2;
|
||||
} else {
|
||||
*end++ = (char) ('0' + exp);
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
static inline char* format_decimal_f32(f32_dec v, char* out, int cnt) {
|
||||
char* p = out;
|
||||
char* end;
|
||||
int point = cnt + v.exp;
|
||||
|
||||
/* print leading zeros if fp < 1 */
|
||||
if (point <= 0) {
|
||||
*p++ = '0', *p++ = '.';
|
||||
for (int i = 0; i < -point; i++) {
|
||||
*p++ = '0';
|
||||
}
|
||||
}
|
||||
|
||||
/* add the remaining digits */
|
||||
end = format_significand_f32(v.sig, p, cnt);
|
||||
while (*(end - 1) == '0') end--;
|
||||
if (point <= 0) {
|
||||
return end;
|
||||
}
|
||||
|
||||
/* insert point or add trailing zeros */
|
||||
int digs = end - p, frac = digs - point;
|
||||
if (digs > point) {
|
||||
for (int i = 0; i < frac; i++) {
|
||||
*(end - i) = *(end - i - 1);
|
||||
}
|
||||
p[point] = '.';
|
||||
end++;
|
||||
} else {
|
||||
for (int i = 0; i < point - digs; i++) {
|
||||
*end++ = '0';
|
||||
}
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
static inline char* write_dec_f32(f32_dec dec, char* p) {
|
||||
int cnt = ctz10_u32(dec.sig);
|
||||
int dot = cnt + dec.exp;
|
||||
int sci_exp = dot - 1;
|
||||
bool exp_fmt = sci_exp < -6 || sci_exp > 20;
|
||||
bool has_dot = dot < cnt;
|
||||
|
||||
if (exp_fmt) {
|
||||
return format_exponent_f32(dec, p, cnt);
|
||||
}
|
||||
if (has_dot) {
|
||||
return format_decimal_f32(dec, p, cnt);
|
||||
}
|
||||
|
||||
char* end = p + dot;
|
||||
p = format_integer_u32(dec.sig, p, cnt);
|
||||
while (p < end) *p++ = '0';
|
||||
return end;
|
||||
}
|
||||
|
||||
static inline uint32_t f32toraw(float fp) {
|
||||
union {
|
||||
uint32_t u32;
|
||||
float f32;
|
||||
} uval;
|
||||
uval.f32 = fp;
|
||||
return uval.u32;
|
||||
}
|
||||
|
||||
static inline uint64_t pow10_ceil_sig_f32(int32_t k)
|
||||
{
|
||||
// There are unique beta and r such that 10^k = beta 2^r and
|
||||
// 2^63 <= beta < 2^64, namely r = floor(log_2 10^k) - 63 and
|
||||
// beta = 2^-r 10^k.
|
||||
// Let g = ceil(beta), so (g-1) 2^r < 10^k <= g 2^r, with the latter
|
||||
// value being a pretty good overestimate for 10^k.
|
||||
|
||||
// NB: Since for all the required exponents k, we have g < 2^64,
|
||||
// all constants can be stored in 128-bit integers.
|
||||
// reference from:
|
||||
// https://github.com/abolz/Drachennest/blob/master/src/schubfach_32.cc#L144
|
||||
|
||||
#define KMAX 45
|
||||
#define KMIN -31
|
||||
static const uint64_t g[KMAX - KMIN + 1] = {
|
||||
0x81CEB32C4B43FCF5, // -31
|
||||
0xA2425FF75E14FC32, // -30
|
||||
0xCAD2F7F5359A3B3F, // -29
|
||||
0xFD87B5F28300CA0E, // -28
|
||||
0x9E74D1B791E07E49, // -27
|
||||
0xC612062576589DDB, // -26
|
||||
0xF79687AED3EEC552, // -25
|
||||
0x9ABE14CD44753B53, // -24
|
||||
0xC16D9A0095928A28, // -23
|
||||
0xF1C90080BAF72CB2, // -22
|
||||
0x971DA05074DA7BEF, // -21
|
||||
0xBCE5086492111AEB, // -20
|
||||
0xEC1E4A7DB69561A6, // -19
|
||||
0x9392EE8E921D5D08, // -18
|
||||
0xB877AA3236A4B44A, // -17
|
||||
0xE69594BEC44DE15C, // -16
|
||||
0x901D7CF73AB0ACDA, // -15
|
||||
0xB424DC35095CD810, // -14
|
||||
0xE12E13424BB40E14, // -13
|
||||
0x8CBCCC096F5088CC, // -12
|
||||
0xAFEBFF0BCB24AAFF, // -11
|
||||
0xDBE6FECEBDEDD5BF, // -10
|
||||
0x89705F4136B4A598, // -9
|
||||
0xABCC77118461CEFD, // -8
|
||||
0xD6BF94D5E57A42BD, // -7
|
||||
0x8637BD05AF6C69B6, // -6
|
||||
0xA7C5AC471B478424, // -5
|
||||
0xD1B71758E219652C, // -4
|
||||
0x83126E978D4FDF3C, // -3
|
||||
0xA3D70A3D70A3D70B, // -2
|
||||
0xCCCCCCCCCCCCCCCD, // -1
|
||||
0x8000000000000000, // 0
|
||||
0xA000000000000000, // 1
|
||||
0xC800000000000000, // 2
|
||||
0xFA00000000000000, // 3
|
||||
0x9C40000000000000, // 4
|
||||
0xC350000000000000, // 5
|
||||
0xF424000000000000, // 6
|
||||
0x9896800000000000, // 7
|
||||
0xBEBC200000000000, // 8
|
||||
0xEE6B280000000000, // 9
|
||||
0x9502F90000000000, // 10
|
||||
0xBA43B74000000000, // 11
|
||||
0xE8D4A51000000000, // 12
|
||||
0x9184E72A00000000, // 13
|
||||
0xB5E620F480000000, // 14
|
||||
0xE35FA931A0000000, // 15
|
||||
0x8E1BC9BF04000000, // 16
|
||||
0xB1A2BC2EC5000000, // 17
|
||||
0xDE0B6B3A76400000, // 18
|
||||
0x8AC7230489E80000, // 19
|
||||
0xAD78EBC5AC620000, // 20
|
||||
0xD8D726B7177A8000, // 21
|
||||
0x878678326EAC9000, // 22
|
||||
0xA968163F0A57B400, // 23
|
||||
0xD3C21BCECCEDA100, // 24
|
||||
0x84595161401484A0, // 25
|
||||
0xA56FA5B99019A5C8, // 26
|
||||
0xCECB8F27F4200F3A, // 27
|
||||
0x813F3978F8940985, // 28
|
||||
0xA18F07D736B90BE6, // 29
|
||||
0xC9F2C9CD04674EDF, // 30
|
||||
0xFC6F7C4045812297, // 31
|
||||
0x9DC5ADA82B70B59E, // 32
|
||||
0xC5371912364CE306, // 33
|
||||
0xF684DF56C3E01BC7, // 34
|
||||
0x9A130B963A6C115D, // 35
|
||||
0xC097CE7BC90715B4, // 36
|
||||
0xF0BDC21ABB48DB21, // 37
|
||||
0x96769950B50D88F5, // 38
|
||||
0xBC143FA4E250EB32, // 39
|
||||
0xEB194F8E1AE525FE, // 40
|
||||
0x92EFD1B8D0CF37BF, // 41
|
||||
0xB7ABC627050305AE, // 42
|
||||
0xE596B7B0C643C71A, // 43
|
||||
0x8F7E32CE7BEA5C70, // 44
|
||||
0xB35DBF821AE4F38C, // 45
|
||||
};
|
||||
|
||||
xassert(k >= KMIN && k <= KMAX);
|
||||
return g[k - KMIN];
|
||||
#undef KMIN
|
||||
#undef KMAX
|
||||
}
|
||||
|
||||
static inline uint32_t round_odd_f32(uint64_t g, uint32_t cp) {
|
||||
const uint128_t p = ((uint128_t)g) * cp;
|
||||
const uint32_t y1 = (uint64_t)(p >> 64);
|
||||
const uint32_t y0 = ((uint64_t)(p)) >> 32;
|
||||
return y1 | (y0 > 1);
|
||||
}
|
||||
|
||||
/**
|
||||
Rendering float point number into decimal.
|
||||
The function used Schubfach algorithm, reference:
|
||||
The Schubfach way to render doubles, Raffaello Giulietti, 2022-03-20.
|
||||
https://drive.google.com/file/d/1gp5xv4CAa78SVgCeWfGqqI4FfYYYuNFb
|
||||
https://mail.openjdk.java.net/pipermail/core-libs-dev/2021-November/083536.html
|
||||
https://github.com/openjdk/jdk/pull/3402 (Java implementation)
|
||||
https://github.com/abolz/Drachennest (C++ implementation)
|
||||
*/
|
||||
static inline f32_dec f32todec(uint32_t rsig, int32_t rexp, uint32_t c, int32_t q) {
|
||||
uint32_t cbl, cb, cbr, vbl, vb, vbr, lower, upper, s;
|
||||
int32_t k, h;
|
||||
bool even, irregular, w_inside, u_inside;
|
||||
f32_dec dec;
|
||||
|
||||
even = !(c & 1);
|
||||
irregular = rsig == 0 && rexp > 1;
|
||||
|
||||
cbl = 4 * c - 2 + irregular;
|
||||
cb = 4 * c;
|
||||
cbr = 4 * c + 2;
|
||||
|
||||
k = (q * 1262611 - (irregular ? 524031 : 0)) >> 22;
|
||||
h = q + ((-k) * 1741647 >> 19) + 1;
|
||||
uint64_t pow10 = pow10_ceil_sig_f32(-k);
|
||||
vbl = round_odd_f32(pow10, cbl << h);
|
||||
vb = round_odd_f32(pow10, cb << h);
|
||||
vbr = round_odd_f32(pow10, cbr << h);
|
||||
|
||||
|
||||
lower = vbl + !even;
|
||||
upper = vbr - !even;
|
||||
|
||||
s = vb / 4;
|
||||
if (s >= 10) {
|
||||
uint64_t sp = s / 10;
|
||||
bool up_inside = lower <= (40 * sp);
|
||||
bool wp_inside = (40 * sp + 40) <= upper;
|
||||
if (up_inside != wp_inside) {
|
||||
dec.sig = sp + wp_inside;
|
||||
dec.exp = k + 1;
|
||||
return dec;
|
||||
}
|
||||
}
|
||||
|
||||
u_inside = lower <= (4 * s);
|
||||
w_inside = (4 * s + 4) <= upper;
|
||||
if (u_inside != w_inside) {
|
||||
dec.sig = s + w_inside;
|
||||
dec.exp = k;
|
||||
return dec;
|
||||
}
|
||||
|
||||
uint64_t mid = 4 * s + 2;
|
||||
bool round_up = vb > mid || (vb == mid && (s & 1) != 0);
|
||||
dec.sig = s + round_up;
|
||||
dec.exp = k;
|
||||
return dec;
|
||||
}
|
||||
|
||||
int f32toa(char *out, float fp) {
|
||||
char* p = out;
|
||||
uint32_t raw = f32toraw(fp);
|
||||
bool neg;
|
||||
uint32_t rsig, c;
|
||||
int32_t rexp, q;
|
||||
|
||||
neg = ((raw >> (F32_BITS - 1)) != 0);
|
||||
rsig = raw & F32_SIG_MASK;
|
||||
rexp = (int32_t)((raw & F32_EXP_MASK) >> F32_SIG_BITS);
|
||||
|
||||
/* check infinity and nan */
|
||||
if (unlikely(rexp == F32_INF_NAN_EXP)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check negative numbers */
|
||||
*p = '-';
|
||||
p += neg;
|
||||
|
||||
/* simple case of 0.0 */
|
||||
if ((raw << 1) == 0) {
|
||||
*p++ = '0';
|
||||
return p - out;
|
||||
}
|
||||
|
||||
if (likely(rexp != 0)) {
|
||||
/* double is normal */
|
||||
c = rsig | F32_HIDDEN_BIT;
|
||||
q = rexp - F32_EXP_BIAS - F32_SIG_BITS;
|
||||
|
||||
/* fast path for integer */
|
||||
if (q <= 0 && q >= -F32_SIG_BITS && is_div_pow2(c, -q)) {
|
||||
uint32_t u = c >> -q;
|
||||
p = format_integer_u32(u, p, ctz10_u32(u));
|
||||
return p - out;
|
||||
}
|
||||
} else {
|
||||
c = rsig;
|
||||
q = 1 - F32_EXP_BIAS - F32_SIG_BITS;
|
||||
}
|
||||
|
||||
f32_dec dec = f32todec(rsig, rexp, c, q);
|
||||
p = write_dec_f32(dec, p);
|
||||
return p - out;
|
||||
}
|
||||
|
||||
#undef F32_BITS
|
||||
#undef F32_EXP_BITS
|
||||
#undef F32_SIG_BITS
|
||||
#undef F32_EXP_MASK
|
||||
#undef F32_SIG_MASK
|
||||
#undef F32_EXP_BIAS
|
||||
#undef F32_INF_NAN_EXP
|
||||
#undef F32_HIDDEN_BIT
|
||||
|
|
@ -16,84 +16,6 @@
|
|||
|
||||
#include "native.h"
|
||||
|
||||
static inline int is_zero_sse(__m128i v) {
|
||||
return _mm_testz_si128(v, v);
|
||||
}
|
||||
|
||||
#if USE_AVX
|
||||
static inline int is_zero_avx(__m256i v) {
|
||||
return _mm256_testz_si256(v, v);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t lzero(const char *sp, size_t nb) {
|
||||
size_t n = nb;
|
||||
const char * p = sp;
|
||||
|
||||
#if USE_AVX
|
||||
/* 32-byte loop */
|
||||
while (n >= 32) {
|
||||
if (!is_zero_avx(_mm256_loadu_si256((const void *)p))) {
|
||||
_mm256_zeroupper();
|
||||
return 1;
|
||||
} else {
|
||||
p += 32;
|
||||
n -= 32;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear upper half to avoid AVX-SSE transition penalty */
|
||||
_mm256_zeroupper();
|
||||
#endif
|
||||
|
||||
/* 16-byte loop */
|
||||
while (n >= 16) {
|
||||
if (!is_zero_sse(_mm_loadu_si128((const void *)p))) {
|
||||
return 1;
|
||||
} else {
|
||||
p += 16;
|
||||
n -= 16;
|
||||
}
|
||||
}
|
||||
|
||||
/* 8-byte test */
|
||||
if (n >= 8) {
|
||||
if (*(uint64_t *)p) {
|
||||
return 1;
|
||||
} else {
|
||||
p += 8;
|
||||
n -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* 4-byte test */
|
||||
if (n >= 4) {
|
||||
if (*(uint32_t *)p) {
|
||||
return 1;
|
||||
} else {
|
||||
p += 4;
|
||||
n -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2-byte test */
|
||||
if (n >= 2) {
|
||||
if (*(uint16_t *)p) {
|
||||
return 1;
|
||||
} else {
|
||||
p += 2;
|
||||
n -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* the final byte */
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return *p != 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_AVX2
|
||||
static const uintptr_t ALIGN_MASK = 31;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,485 +1,405 @@
|
|||
/* Copyright 2018 Ulf Adams.
|
||||
* Modifications copyright 2021 ByteDance Inc.
|
||||
/* Copyright 2020 Alexander Bolz
|
||||
*
|
||||
* The contents of this file may be used under the terms of the Apache License,
|
||||
* Version 2.0.
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
*
|
||||
* (See accompanying file LICENSE-Apache or copy at
|
||||
* http: *www.apache.org/licenses/LICENSE-2.0)
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE-Boost or copy at
|
||||
* https: *www.boost.org/LICENSE_1_0.txt)
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer,
|
||||
* must be included in all copies of the Software, in whole or in part, and
|
||||
* all derivative works of the Software, unless such copies or derivative
|
||||
* works are solely in the form of machine-executable object code generated by
|
||||
* a source language processor.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this software
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* This file may have been modified by ByteDance authors. All ByteDance
|
||||
* Modifications are Copyright 2022 ByteDance Authors.
|
||||
*/
|
||||
#include "native.h"
|
||||
#include "ryu_tab.h"
|
||||
|
||||
/* use 128-bit type for performance */
|
||||
#include "native.h"
|
||||
#include "tab.h"
|
||||
#include "test/xassert.h"
|
||||
|
||||
#define F64_BITS 64
|
||||
#define F64_EXP_BITS 11
|
||||
#define F64_SIG_BITS 52
|
||||
#define F64_EXP_MASK 0x7FF0000000000000ull // middle 11 bits
|
||||
#define F64_SIG_MASK 0x000FFFFFFFFFFFFFull // lower 52 bits
|
||||
#define F64_EXP_BIAS 1023
|
||||
#define F64_INF_NAN_EXP 0x7FF
|
||||
#define F64_HIDDEN_BIT 0x0010000000000000ull
|
||||
|
||||
struct f64_dec {
|
||||
uint64_t sig;
|
||||
int64_t exp;
|
||||
};
|
||||
typedef struct f64_dec f64_dec;
|
||||
|
||||
typedef __uint128_t uint128_t;
|
||||
|
||||
/* Returns e == 0 ? 1 : ceil(log_2(5^e)) */
|
||||
static inline int32_t pow5bits(const int32_t e) {
|
||||
return (int32_t) (((((uint32_t) e) * 1217359) >> 19) + 1);
|
||||
}
|
||||
|
||||
/* Returns floor(log_10(2^e)) */
|
||||
static inline uint32_t log10pow2(const int32_t e) {
|
||||
return (((uint32_t) e) * 78913) >> 18;
|
||||
}
|
||||
|
||||
/* Returns floor(log_10(5^e)) */
|
||||
static inline uint32_t log10pow5(const int32_t e) {
|
||||
return (((uint32_t) e) * 732923) >> 20;
|
||||
}
|
||||
|
||||
static inline uint32_t pow5factor(uint64_t v) {
|
||||
uint64_t m_inv5 = 14757395258967641293u; // *5 = 1(mod 2^64)
|
||||
uint64_t n_div5 = 3689348814741910323u; // =2^64 / 5
|
||||
uint32_t cnt = 0;
|
||||
for (;;) {
|
||||
v *= m_inv5;
|
||||
if (v > n_div5)
|
||||
break;
|
||||
++cnt;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* Returns true if value is divisible by 5^p */
|
||||
static inline bool ispow5(const uint64_t v, const uint32_t p) {
|
||||
return pow5factor(v) >= p;
|
||||
}
|
||||
|
||||
/* Returns true if value is divisible by 2^p */
|
||||
static inline bool ispow2(const uint64_t v, const uint32_t p) {
|
||||
return (v & ((1ull << p) - 1)) == 0;
|
||||
}
|
||||
|
||||
/* Requires 0 <= v < v < 100000000000000000L */
|
||||
static inline uint32_t ctz10(const uint64_t v) {
|
||||
if (v < 10) return 1;
|
||||
if (v < 100) return 2;
|
||||
if (v < 1000) return 3;
|
||||
if (v < 10000) return 4;
|
||||
if (v < 100000) return 5;
|
||||
if (v < 1000000) return 6;
|
||||
if (v < 10000000) return 7;
|
||||
if (v < 100000000) return 8;
|
||||
if (v < 1000000000) return 9;
|
||||
if (v < 10000000000) return 10;
|
||||
if (v < 100000000000) return 11;
|
||||
if (v < 1000000000000) return 12;
|
||||
if (v < 10000000000000) return 13;
|
||||
if (v < 100000000000000) return 14;
|
||||
if (v < 1000000000000000) return 15;
|
||||
if (v < 10000000000000000) return 16;
|
||||
static inline unsigned ctz10(const uint64_t v) {
|
||||
xassert(0 <= v && v < 100000000000000000ull);
|
||||
if (v >= 10000000000ull) {
|
||||
if (v < 100000000000ull) return 11;
|
||||
if (v < 1000000000000ull) return 12;
|
||||
if (v < 10000000000000ull) return 13;
|
||||
if (v < 100000000000000ull) return 14;
|
||||
if (v < 1000000000000000ull) return 15;
|
||||
if (v < 10000000000000000ull) return 16;
|
||||
return 17;
|
||||
}
|
||||
if (v < 10ull) return 1;
|
||||
if (v < 100ull) return 2;
|
||||
if (v < 1000ull) return 3;
|
||||
if (v < 10000ull) return 4;
|
||||
if (v < 100000ull) return 5;
|
||||
if (v < 1000000ull) return 6;
|
||||
if (v < 10000000ull) return 7;
|
||||
if (v < 100000000ull) return 8;
|
||||
if (v < 1000000000ull) return 9;
|
||||
return 10;
|
||||
|
||||
}
|
||||
|
||||
/* Best case: use 128-bit type */
|
||||
static inline uint64_t mulshift(const uint64_t m, const uint64_t *mul, const int32_t j) {
|
||||
uint128_t lo = ((uint128_t) m) * mul[0];
|
||||
uint128_t hi = ((uint128_t) m) * mul[1];
|
||||
return (uint64_t) (((lo >> 64) + hi) >> (j - 64));
|
||||
}
|
||||
static inline char* format_significand(uint64_t sig, char *out, int cnt) {
|
||||
char *p = out + cnt;
|
||||
int ctz = 0;
|
||||
|
||||
#define mul_shift_all(m, mul, j, shift) \
|
||||
vp = mulshift(4 * m + 2, mul, j); \
|
||||
vm = mulshift(4 * m - 1 - shift, mul, j); \
|
||||
vr = mulshift(4 * m, mul, j);
|
||||
|
||||
#define copy_two_digs(dst, src) \
|
||||
*(dst) = *(src); \
|
||||
*(dst+1) = *(src+1);
|
||||
|
||||
/* A floating decimal representing man * 10^exp */
|
||||
typedef struct f64_d {
|
||||
uint64_t man;
|
||||
int32_t exp;
|
||||
} f64_d;
|
||||
|
||||
static inline f64_d f64tod(const uint64_t man,const uint32_t exp) {
|
||||
int32_t e2;
|
||||
uint64_t m2;
|
||||
if (exp == 0) {
|
||||
/* subtract 2 so that the bounds computation has 2 additional bits */
|
||||
e2 = 1 - 1023 - 52 - 2;
|
||||
m2 = man;
|
||||
} else {
|
||||
e2 = (int32_t) exp - 1023 - 52 - 2;
|
||||
m2 = (1ull << 52) | man;
|
||||
}
|
||||
bool even = (m2 & 1) == 0;
|
||||
|
||||
/* Step 2: Determine the interval of valid decimal representations */
|
||||
uint64_t mv = 4 * m2;
|
||||
/* Implicit bool -> int conversion. True is 1, false is 0 */
|
||||
uint32_t shift = man != 0 || exp <= 1;
|
||||
|
||||
/* Step 3: Convert to a decimal power base using 128-bit arithmetic */
|
||||
uint64_t vr, vp, vm;
|
||||
int32_t e10;
|
||||
bool vmzeros = false;
|
||||
bool vrzeros = false;
|
||||
if (e2 >= 0) {
|
||||
|
||||
uint32_t q = log10pow2(e2) - (e2 > 3); // max(0, log10pow2(e2) - 1)
|
||||
e10 = (int32_t) q;
|
||||
int32_t k = DOUBLE_POW5_INV_BITCOUNT + pow5bits((int32_t) q) - 1;
|
||||
int32_t i = -e2 + (int32_t) q + k;
|
||||
uint64_t *mul = (uint64_t*)DOUBLE_POW5_INV_SPLIT[q];
|
||||
/* {vm, vr, vp} * 10^e10 = {mm, mv, mp} * 2^e2
|
||||
* mp = 4 * m2 + 2
|
||||
* mm = mv - 1 - shift
|
||||
*/
|
||||
mul_shift_all(m2, mul, i, shift)
|
||||
|
||||
if (q <= 21) {
|
||||
if (mv % 5 == 0) {
|
||||
vrzeros = ispow5(mv, q);
|
||||
} else if (even) {
|
||||
/* Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q
|
||||
* <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q
|
||||
* <=> true && pow5Factor(mm) >= q, since e2 >= q.
|
||||
*/
|
||||
vmzeros = ispow5(mv - 1 - shift, q);
|
||||
} else {
|
||||
/* Same as min(e2 + 1, pow5Factor(mp)) >= q. */
|
||||
vp -= ispow5(mv + 2, q);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t q = log10pow5(-e2) - (-e2 > 1); // max(0, log10pow5(-e2) - 1)
|
||||
e10 = (int32_t) q + e2;
|
||||
int32_t i = -e2 - (int32_t) q;
|
||||
int32_t k = pow5bits(i) - DOUBLE_POW5_BITCOUNT;
|
||||
int32_t j = (int32_t) q - k;
|
||||
uint64_t *mul = (uint64_t*)DOUBLE_POW5_SPLIT[i];
|
||||
/* {vm, vr, vp} * 10^e10 = {mm, mv, mp} * 2^e2 */
|
||||
mul_shift_all(m2, mul, j, shift)
|
||||
|
||||
if (q <= 1) {
|
||||
/* {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing
|
||||
* 0 bits. mv = 4 * m2, so it always has at least two trailing 0 bits.
|
||||
*/
|
||||
vrzeros = true;
|
||||
if (even) {
|
||||
/* mm = mv - 1 - shift, so it has 1 trailing 0 bit if shift = 1 */
|
||||
vmzeros = shift == 1;
|
||||
} else {
|
||||
/* mp = mv + 2, so it always has at least one trailing 0 bit */
|
||||
--vp;
|
||||
}
|
||||
} else if (q < 63) {
|
||||
vrzeros = ispow2(mv, q);
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 4: Find the shortest decimal representation in the interval */
|
||||
int32_t removed = 0;
|
||||
uint8_t lastrmdig = 0;
|
||||
uint64_t dman;
|
||||
/* On average, we remove ~2 DIGs */
|
||||
if (vmzeros || vrzeros) {
|
||||
/* General case, which happens rarely (~0.7%) */
|
||||
for (;;) {
|
||||
uint64_t vpdiv10 = vp / 10;
|
||||
uint64_t vmdiv10 = vm / 10;
|
||||
if (vpdiv10 <= vmdiv10) {
|
||||
break;
|
||||
}
|
||||
uint32_t vmmod10 = ((uint32_t) vm) - 10 * ((uint32_t) vmdiv10);
|
||||
uint64_t vrdiv10 = vr / 10;
|
||||
uint32_t vrmod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrdiv10);
|
||||
vmzeros &= vmmod10 == 0;
|
||||
vrzeros &= lastrmdig == 0;
|
||||
lastrmdig = (uint8_t) vrmod10;
|
||||
vr = vrdiv10;
|
||||
vp = vpdiv10;
|
||||
vm = vmdiv10;
|
||||
++removed;
|
||||
}
|
||||
if (vmzeros) {
|
||||
for (;;) {
|
||||
uint64_t vmdiv10 = vm / 10;
|
||||
uint32_t vmmod10 = ((uint32_t) vm) - 10 * ((uint32_t) vmdiv10);
|
||||
if (vmmod10 != 0) {
|
||||
break;
|
||||
}
|
||||
uint64_t vpdiv10 = vp / 10;
|
||||
uint64_t vrdiv10 = vr / 10;
|
||||
uint32_t vrmod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrdiv10);
|
||||
vrzeros &= lastrmdig == 0;
|
||||
lastrmdig = (uint8_t) vrmod10;
|
||||
vr = vrdiv10;
|
||||
vp = vpdiv10;
|
||||
vm = vmdiv10;
|
||||
++removed;
|
||||
}
|
||||
}
|
||||
if (vrzeros && lastrmdig == 5 && vr % 2 == 0) {
|
||||
/* Round even if the exact number is .....50..0 */
|
||||
lastrmdig = 4;
|
||||
}
|
||||
/* We need to take vr + 1 if vr is outside bounds or we need to round up */
|
||||
dman = vr + ((vr == vm && (!even || !vmzeros)) || lastrmdig >= 5);
|
||||
} else {
|
||||
/* Specialized for the common case (~99.3%). Percentages below are relative to this */
|
||||
bool roundup= false;
|
||||
uint64_t vpdiv100 = vp / 100;
|
||||
uint64_t vmdiv100 = vm / 100;
|
||||
if (vpdiv100 > vmdiv100) { // Optimization: remove two DIGs at a time (~86.2%).
|
||||
uint64_t vrdiv100 = vr / 100;
|
||||
uint32_t vrmod100 = ((uint32_t) vr) - 100 * ((uint32_t) vrdiv100);
|
||||
roundup = vrmod100 >= 50;
|
||||
vr = vrdiv100;
|
||||
vp = vpdiv100;
|
||||
vm = vmdiv100;
|
||||
removed += 2;
|
||||
}
|
||||
/* Loop iterations below (approximately), without optimization above:
|
||||
* 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02%
|
||||
* Loop iterations below (approximately), with optimization above:
|
||||
* 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02%
|
||||
*/
|
||||
for (;;) {
|
||||
uint64_t vpdiv10 = vp / 10;
|
||||
uint64_t vmdiv10 = vm / 10;
|
||||
if (vpdiv10 <= vmdiv10) {
|
||||
break;
|
||||
}
|
||||
uint64_t vrdiv10 = vr / 10;
|
||||
uint32_t vrmod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrdiv10);
|
||||
roundup = vrmod10 >= 5;
|
||||
vr = vrdiv10;
|
||||
vp = vpdiv10;
|
||||
vm = vmdiv10;
|
||||
++removed;
|
||||
}
|
||||
/* We need to take vr + 1 if vr is outside bounds or we need to round up */
|
||||
dman = vr + (vr == vm || roundup);
|
||||
}
|
||||
f64_d fd = {
|
||||
.exp = e10 + removed,
|
||||
.man = dman,
|
||||
};
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Print the decimal DIGs from mantissa */
|
||||
static inline void print_mantissa(uint64_t man, char *out, int mlen) {
|
||||
/* We have at most 17 DIGs, and uint32_t can store 9 DIGs.
|
||||
* If man doesn't fit into uint32_t, we cut off 8 DIGs,
|
||||
* so the rest will fit into uint32_t.
|
||||
*/
|
||||
char *r = out + mlen;
|
||||
if (man < 10) {}
|
||||
if ((man >> 32) != 0) {
|
||||
/* Expensive 64-bit division */
|
||||
uint64_t q = man / 100000000;
|
||||
uint32_t man2 = ((uint32_t) man) - 100000000 * ((uint32_t) q);
|
||||
man = q;
|
||||
|
||||
uint32_t c = man2 % 10000;
|
||||
man2 /= 10000;
|
||||
uint32_t d = man2 % 10000;
|
||||
if ((sig >> 32) != 0) {
|
||||
uint64_t q = sig / 100000000;
|
||||
uint32_t r = ((uint32_t)sig) - 100000000 * ((uint32_t) q);
|
||||
sig = q;
|
||||
if (r != 0) {
|
||||
uint32_t c = r % 10000;
|
||||
r /= 10000;
|
||||
uint32_t d = r % 10000;
|
||||
uint32_t c0 = (c % 100) << 1;
|
||||
uint32_t c1 = (c / 100) << 1;
|
||||
uint32_t d0 = (d % 100) << 1;
|
||||
uint32_t d1 = (d / 100) << 1;
|
||||
copy_two_digs(r - 2, DIG_TAB + c0)
|
||||
copy_two_digs(r - 4, DIG_TAB + c1)
|
||||
copy_two_digs(r - 6, DIG_TAB + d0)
|
||||
copy_two_digs(r - 8, DIG_TAB + d1)
|
||||
r -= 8;
|
||||
copy_two_digs(p - 2, Digits + c0);
|
||||
copy_two_digs(p - 4, Digits + c1);
|
||||
copy_two_digs(p - 6, Digits + d0);
|
||||
copy_two_digs(p - 8, Digits + d1);
|
||||
} else {
|
||||
ctz += 8;
|
||||
}
|
||||
uint32_t man2 = (uint32_t) man;
|
||||
while (man2 >= 10000) {
|
||||
#ifdef __clang__ // https://bugs.llvm.org/show_bug.cgi?id=38217
|
||||
uint32_t c = man2 - 10000 * (man2 / 10000);
|
||||
#else
|
||||
uint32_t c = man2 % 10000;
|
||||
#endif
|
||||
man2 /= 10000;
|
||||
p -= 8;
|
||||
}
|
||||
|
||||
uint32_t sig2 = (uint32_t)sig;
|
||||
while (sig2 >= 10000) {
|
||||
uint32_t c = sig2 - 10000 * (sig2 / 10000);
|
||||
sig2 /= 10000;
|
||||
uint32_t c0 = (c % 100) << 1;
|
||||
uint32_t c1 = (c / 100) << 1;
|
||||
copy_two_digs(r - 2, DIG_TAB + c0)
|
||||
copy_two_digs(r - 4, DIG_TAB + c1)
|
||||
r -= 4;
|
||||
copy_two_digs(p - 2, Digits + c0);
|
||||
copy_two_digs(p - 4, Digits + c1);
|
||||
p -= 4;
|
||||
}
|
||||
if (man2 >= 100) {
|
||||
uint32_t c = (man2 % 100) << 1;
|
||||
man2 /= 100;
|
||||
copy_two_digs(r - 2, DIG_TAB + c)
|
||||
r -= 2;
|
||||
if (sig2 >= 100) {
|
||||
uint32_t c = (sig2 % 100) << 1;
|
||||
sig2 /= 100;
|
||||
copy_two_digs(p - 2, Digits + c);
|
||||
p -= 2;
|
||||
}
|
||||
if (man2 >= 10) {
|
||||
uint32_t c = man2 << 1;
|
||||
copy_two_digs(r - 2, DIG_TAB + c)
|
||||
if (sig2 >= 10) {
|
||||
uint32_t c = sig2 << 1;
|
||||
copy_two_digs(p - 2, Digits + c);
|
||||
} else {
|
||||
*out = (char) ('0' + man2);
|
||||
*out = (char) ('0' + sig2);
|
||||
}
|
||||
return out + cnt - ctz;
|
||||
}
|
||||
|
||||
static inline int print_exponent(f64_d v, char *out, int mlen) {
|
||||
int idx = 0;
|
||||
|
||||
print_mantissa(v.man, out + idx + 1, mlen);
|
||||
|
||||
/* Print decimal point if needed */
|
||||
out[idx] = out[idx + 1];
|
||||
if (mlen > 1) {
|
||||
out[idx + 1] = '.';
|
||||
idx += mlen + 1;
|
||||
} else {
|
||||
++idx;
|
||||
static inline char* format_integer(uint64_t sig, char *out, unsigned cnt) {
|
||||
char *p = out + cnt;
|
||||
if ((sig >> 32) != 0) {
|
||||
uint64_t q = sig / 100000000;
|
||||
uint32_t r = ((uint32_t)sig) - 100000000 * ((uint32_t) q);
|
||||
sig = q;
|
||||
uint32_t c = r % 10000;
|
||||
r /= 10000;
|
||||
uint32_t d = r % 10000;
|
||||
uint32_t c0 = (c % 100) << 1;
|
||||
uint32_t c1 = (c / 100) << 1;
|
||||
uint32_t d0 = (d % 100) << 1;
|
||||
uint32_t d1 = (d / 100) << 1;
|
||||
copy_two_digs(p - 2, Digits + c0);
|
||||
copy_two_digs(p - 4, Digits + c1);
|
||||
copy_two_digs(p - 6, Digits + d0);
|
||||
copy_two_digs(p - 8, Digits + d1);
|
||||
p -= 8;
|
||||
}
|
||||
|
||||
/* Print the exponent */
|
||||
out[idx++] = 'e';
|
||||
int32_t exp = v.exp + (int32_t) mlen - 1;
|
||||
uint32_t sig2 = (uint32_t)sig;
|
||||
while (sig2 >= 10000) {
|
||||
uint32_t c = sig2 - 10000 * (sig2 / 10000);
|
||||
sig2 /= 10000;
|
||||
uint32_t c0 = (c % 100) << 1;
|
||||
uint32_t c1 = (c / 100) << 1;
|
||||
copy_two_digs(p - 2, Digits + c0);
|
||||
copy_two_digs(p - 4, Digits + c1);
|
||||
p -= 4;
|
||||
}
|
||||
if (sig2 >= 100) {
|
||||
uint32_t c = (sig2 % 100) << 1;
|
||||
sig2 /= 100;
|
||||
copy_two_digs(p - 2, Digits + c);
|
||||
p -= 2;
|
||||
}
|
||||
if (sig2 >= 10) {
|
||||
uint32_t c = sig2 << 1;
|
||||
copy_two_digs(p - 2, Digits + c);
|
||||
} else {
|
||||
*out = (char) ('0' + sig2);
|
||||
}
|
||||
return out + cnt;
|
||||
}
|
||||
|
||||
static inline char* format_exponent(f64_dec v, char *out, unsigned cnt) {
|
||||
char* p = out + 1;
|
||||
char* end = format_significand(v.sig, p, cnt);
|
||||
while (*(end - 1) == '0') end--;
|
||||
|
||||
/* print decimal point if needed */
|
||||
*out = *p;
|
||||
if (end - p > 1) {
|
||||
*p = '.';
|
||||
} else {
|
||||
end--;
|
||||
}
|
||||
|
||||
/* print the exponent */
|
||||
*end++ = 'e';
|
||||
int32_t exp = v.exp + (int32_t) cnt - 1;
|
||||
if (exp < 0) {
|
||||
out[idx++] = '-';
|
||||
*end++ = '-';
|
||||
exp = -exp;
|
||||
} else {
|
||||
*end++ = '+';
|
||||
}
|
||||
|
||||
if (exp >= 100) {
|
||||
int32_t c = exp % 10;
|
||||
copy_two_digs(out + idx, DIG_TAB + 2 * (exp / 10))
|
||||
out[idx + 2] = (char) ('0' + c);
|
||||
idx += 3;
|
||||
copy_two_digs(end, Digits + 2 * (exp / 10));
|
||||
end[2] = (char) ('0' + c);
|
||||
end += 3;
|
||||
} else if (exp >= 10) {
|
||||
copy_two_digs(out + idx, DIG_TAB + 2 * exp)
|
||||
idx += 2;
|
||||
copy_two_digs(end, Digits + 2 * exp);
|
||||
end += 2;
|
||||
} else {
|
||||
out[idx++] = (char) ('0' + exp);
|
||||
*end++ = (char) ('0' + exp);
|
||||
}
|
||||
|
||||
return idx;
|
||||
return end;
|
||||
}
|
||||
|
||||
static inline int print_decimal(const f64_d v, char *out, int mlen) {
|
||||
int idx = 0;
|
||||
int lzeros = 0;
|
||||
int rzeros = 0;
|
||||
int point = 0;
|
||||
int exp10 = mlen - 1 + v.exp;
|
||||
static inline char* format_decimal(f64_dec v, char* out, unsigned cnt) {
|
||||
char* p = out;
|
||||
char* end;
|
||||
int point = cnt + v.exp;
|
||||
|
||||
/* parse the point idx and additional zeros */
|
||||
if (exp10 < 0) {
|
||||
lzeros = -exp10;
|
||||
point = 1;
|
||||
} else if (exp10 < mlen - 1) {
|
||||
point = 1 + exp10;
|
||||
/* print leading zeros if fp < 1 */
|
||||
if (point <= 0) {
|
||||
*p++ = '0', *p++ = '.';
|
||||
for (int i = 0; i < -point; i++) {
|
||||
*p++ = '0';
|
||||
}
|
||||
}
|
||||
|
||||
/* add the remaining digits */
|
||||
end = format_significand(v.sig, p, cnt);
|
||||
while (*(end - 1) == '0') end--;
|
||||
if (point <= 0) {
|
||||
return end;
|
||||
}
|
||||
|
||||
/* insert point or add trailing zeros */
|
||||
int digs = end - p;
|
||||
if (digs > point) {
|
||||
for (int i = 0; i < digs - point; i++) {
|
||||
*(end - i) = *(end - i - 1);
|
||||
}
|
||||
p[point] = '.';
|
||||
end++;
|
||||
} else {
|
||||
rzeros = exp10 - mlen + 1;
|
||||
for (int i = 0; i < point - digs; i++) {
|
||||
*end++ = '0';
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
/* add left zeros */
|
||||
if (lzeros) {
|
||||
out[idx++] = '0';
|
||||
out[idx++] = '.';
|
||||
point = 0;
|
||||
}
|
||||
for (i = 1; i < lzeros; ++i) {
|
||||
out[idx++] = '0';
|
||||
}
|
||||
|
||||
/* add the mantissa DIGs */
|
||||
print_mantissa(v.man, out + idx, mlen);
|
||||
if (point) {
|
||||
for (i = idx + mlen; i > idx + point; --i) {
|
||||
out[i] = out[i-1];
|
||||
}
|
||||
out[idx + point] = '.';
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
/* add right zeros */
|
||||
idx += mlen;
|
||||
for (i = 0; i < rzeros; ++i) {
|
||||
out[idx++] = '0';
|
||||
}
|
||||
|
||||
return idx;
|
||||
return end;
|
||||
}
|
||||
|
||||
static inline bool f64tod_exct_int(const uint64_t man, const uint32_t exp,
|
||||
f64_d* v) {
|
||||
uint64_t m2 = (1ull << 52) | man; // implicit 1
|
||||
int32_t e2 = (int32_t) exp - 1023 - 52;
|
||||
static inline char* write_dec(f64_dec dec, char* p) {
|
||||
int cnt = ctz10(dec.sig);
|
||||
int dot = cnt + dec.exp;
|
||||
int sci_exp = dot - 1;
|
||||
bool exp_fmt = sci_exp < -6 || sci_exp > 20;
|
||||
bool has_dot = dot < cnt;
|
||||
|
||||
if (e2 > 0 || e2 < -52) {
|
||||
return false;
|
||||
if (exp_fmt) {
|
||||
return format_exponent(dec, p, cnt);
|
||||
}
|
||||
if (has_dot) {
|
||||
return format_decimal(dec, p, cnt);
|
||||
}
|
||||
|
||||
uint64_t mask = (1ull << -e2) - 1;
|
||||
if ((m2 & mask) != 0) { // with fraction
|
||||
return false;
|
||||
}
|
||||
|
||||
v->man = m2 >> -e2;
|
||||
v->exp = 0;
|
||||
return true;
|
||||
char* end = p + dot;
|
||||
p = format_integer(dec.sig, p, cnt);
|
||||
while (p < end) *p++ = '0';
|
||||
return end;
|
||||
}
|
||||
|
||||
static int inline ryu(uint64_t bits, char *out) {
|
||||
/* Step 1: Decode the floating-point number */
|
||||
uint64_t man = bits & ((1ull << 52) - 1);
|
||||
uint32_t exp = (uint32_t) ((bits >> 52) & ((1u << 11) - 1));
|
||||
static inline uint64_t f64toraw(double fp) {
|
||||
union {
|
||||
uint64_t u64;
|
||||
double f64;
|
||||
} uval;
|
||||
uval.f64 = fp;
|
||||
return uval.u64;
|
||||
}
|
||||
|
||||
/* Skip when Infinity */
|
||||
if (exp == ((1u << 11) - 1u)) {
|
||||
static inline uint64_t round_odd(uint64x2 g, uint64_t cp) {
|
||||
const uint128_t x = ((uint128_t)cp) * g.lo;
|
||||
const uint128_t y = ((uint128_t)cp) * g.hi + ((uint64_t)(x >> 64));
|
||||
|
||||
const uint64_t y0 = ((uint64_t)y);
|
||||
const uint64_t y1 = ((uint64_t)(y >> 64));
|
||||
return y1 | (y0 > 1);
|
||||
}
|
||||
|
||||
/**
|
||||
Rendering float point number into decimal.
|
||||
The function used Schubfach algorithm, reference:
|
||||
The Schubfach way to render doubles, Raffaello Giulietti, 2022-03-20.
|
||||
https://drive.google.com/file/d/1gp5xv4CAa78SVgCeWfGqqI4FfYYYuNFb
|
||||
https://mail.openjdk.java.net/pipermail/core-libs-dev/2021-November/083536.html
|
||||
https://github.com/openjdk/jdk/pull/3402 (Java implementation)
|
||||
https://github.com/abolz/Drachennest (C++ implementation)
|
||||
*/
|
||||
static inline f64_dec f64todec(uint64_t rsig, int32_t rexp, uint64_t c, int32_t q) {
|
||||
uint64_t cbl, cb, cbr, vbl, vb, vbr, lower, upper, s;
|
||||
int32_t k, h;
|
||||
bool even, irregular, w_inside, u_inside;
|
||||
f64_dec dec;
|
||||
|
||||
even = !(c & 1);
|
||||
irregular = rsig == 0 && rexp > 1;
|
||||
|
||||
cbl = 4 * c - 2 + irregular;
|
||||
cb = 4 * c;
|
||||
cbr = 4 * c + 2;
|
||||
|
||||
/* q is in [-1500, 1500]
|
||||
k = irregular ? floor(log_10(3/4 * 2^q)) : floor(log10(pow(2^q)))
|
||||
floor(log10(3/4 * 2^q)) = (q * 1262611 - 524031) >> 22
|
||||
floor(log10(pow(2^q))) = (q * 1262611) >> 22 */
|
||||
k = (q * 1262611 - (irregular ? 524031 : 0)) >> 22;
|
||||
|
||||
/* k is in [-1233, 1233]
|
||||
s = floor(V) = floor(c * 2^q * 10^-k)
|
||||
vb = 4V = 4 * c * 2^q * 10^-k */
|
||||
h = q + ((-k) * 1741647 >> 19) + 1;
|
||||
uint64x2 pow10 = pow10_ceil_sig(-k);
|
||||
vbl = round_odd(pow10, cbl << h);
|
||||
vb = round_odd(pow10, cb << h);
|
||||
vbr = round_odd(pow10, cbr << h);
|
||||
|
||||
lower = vbl + !even;
|
||||
upper = vbr - !even;
|
||||
|
||||
s = vb / 4;
|
||||
if (s >= 10) {
|
||||
/* R_k+1 interval contains at most one: up or wp */
|
||||
uint64_t sp = s / 10;
|
||||
bool up_inside = lower <= (40 * sp);
|
||||
bool wp_inside = (40 * sp + 40) <= upper;
|
||||
if (up_inside != wp_inside) {
|
||||
dec.sig = sp + wp_inside;
|
||||
dec.exp = k + 1;
|
||||
return dec;
|
||||
}
|
||||
}
|
||||
|
||||
/* R_k interval contains at least one: u or w */
|
||||
u_inside = lower <= (4 * s);
|
||||
w_inside = (4 * s + 4) <= upper;
|
||||
if (u_inside != w_inside) {
|
||||
dec.sig = s + w_inside;
|
||||
dec.exp = k;
|
||||
return dec;
|
||||
}
|
||||
|
||||
/* R_k interval contains both u or w */
|
||||
uint64_t mid = 4 * s + 2;
|
||||
bool round_up = vb > mid || (vb == mid && (s & 1) != 0);
|
||||
dec.sig = s + round_up;
|
||||
dec.exp = k;
|
||||
return dec;
|
||||
}
|
||||
|
||||
int f64toa(char *out, double fp) {
|
||||
char* p = out;
|
||||
uint64_t raw = f64toraw(fp);
|
||||
bool neg;
|
||||
uint64_t rsig, c;
|
||||
int32_t rexp, q;
|
||||
|
||||
neg = ((raw >> (F64_BITS - 1)) != 0);
|
||||
rsig = raw & F64_SIG_MASK;
|
||||
rexp = (int32_t)((raw & F64_EXP_MASK) >> F64_SIG_BITS);
|
||||
|
||||
/* check infinity and nan */
|
||||
if (unlikely(rexp == F64_INF_NAN_EXP)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
f64_d v;
|
||||
/* for integer from [1, 2^53], can be resepensated exactly by double */
|
||||
bool is_exact_int = f64tod_exct_int(man, exp, &v);
|
||||
if (!is_exact_int){ // find the shortest decimal representation
|
||||
v = f64tod(man, exp);
|
||||
}
|
||||
|
||||
/* Step 5: Print the decimal representation */
|
||||
int idx = 0;
|
||||
uint32_t mlen = ctz10(v.man);
|
||||
int exp10 = mlen - 1 + v.exp;
|
||||
/* The format as Go encoding/json package */
|
||||
bool isexp = exp10 < -6 || exp10 >= 21;
|
||||
|
||||
if (isexp) // exponent format
|
||||
idx += print_exponent(v, out + idx, mlen);
|
||||
else // decimal format
|
||||
idx += print_decimal(v, out + idx, mlen);
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int f64toa(char *out, double val) {
|
||||
int i = 0;
|
||||
char *p = out;
|
||||
uint64_t uval = *(uint64_t *)&val;
|
||||
|
||||
/* negative numbers */
|
||||
if (unlikely(uval >> 63) == 1) {
|
||||
i = 1;
|
||||
uval &= ((1ull << 63) - 1);
|
||||
*p++ = '-';
|
||||
}
|
||||
/* check negative numbers */
|
||||
*p = '-';
|
||||
p += neg;
|
||||
|
||||
/* simple case of 0.0 */
|
||||
if (uval == 0) {
|
||||
*p = '0';
|
||||
return i + 1;
|
||||
if ((raw << 1) == 0) {
|
||||
*p++ = '0';
|
||||
return p - out;
|
||||
}
|
||||
|
||||
/* print the number with Ryu algorithm */
|
||||
int n = ryu(uval, p);
|
||||
return n + i;
|
||||
/* fp = c * 2^q */
|
||||
if (likely(rexp != 0)) {
|
||||
/* double is normal */
|
||||
c = rsig | F64_HIDDEN_BIT;
|
||||
q = rexp - F64_EXP_BIAS - F64_SIG_BITS;
|
||||
|
||||
/* fast path for integer */
|
||||
if (q <= 0 && q >= -F64_SIG_BITS && is_div_pow2(c, -q)) {
|
||||
uint64_t u = c >> -q;
|
||||
p = format_integer(u, p, ctz10(u));
|
||||
return p - out;
|
||||
}
|
||||
|
||||
} else {
|
||||
c = rsig;
|
||||
q = 1 - F64_EXP_BIAS - F64_SIG_BITS;
|
||||
}
|
||||
|
||||
f64_dec dec = f64todec(rsig, rexp, c, q);
|
||||
p = write_dec(dec, p);
|
||||
return p - out;
|
||||
}
|
||||
|
||||
#undef F64_BITS
|
||||
#undef F64_EXP_BITS
|
||||
#undef F64_SIG_BITS
|
||||
#undef F64_EXP_MASK
|
||||
#undef F64_SIG_MASK
|
||||
#undef F64_EXP_BIAS
|
||||
#undef F64_INF_NAN_EXP
|
||||
#undef F64_HIDDEN_BIT
|
||||
|
|
@ -15,19 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "native.h"
|
||||
|
||||
static const char Digits[200] = {
|
||||
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
|
||||
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
|
||||
'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
|
||||
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
|
||||
'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
|
||||
'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
|
||||
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
|
||||
'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
|
||||
'8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
|
||||
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9',
|
||||
};
|
||||
#include "tab.h"
|
||||
|
||||
static const char Vec16xA0[16] __attribute__((aligned(16))) = {
|
||||
'0', '0', '0', '0', '0', '0', '0', '0',
|
||||
|
|
|
|||
|
|
@ -21,3 +21,4 @@
|
|||
#include "atof_eisel_lemire.c"
|
||||
#include "atof_native.c"
|
||||
#include "scanning.c"
|
||||
#include "f32toa.c"
|
||||
|
|
@ -101,7 +101,6 @@ int f64toa(char *out, double val);
|
|||
int i64toa(char *out, int64_t val);
|
||||
int u64toa(char *out, uint64_t val);
|
||||
|
||||
size_t lzero(const char *sp, size_t nb);
|
||||
size_t lspace(const char *sp, size_t nb, size_t p);
|
||||
|
||||
ssize_t quote(const char *sp, ssize_t nb, char *dp, ssize_t *dn, uint64_t flags);
|
||||
|
|
|
|||
|
|
@ -268,10 +268,8 @@ static inline uint8_t escape_mask4(const char *sp) {
|
|||
|
||||
static inline ssize_t memcchr_quote_unsafe(const char *sp, ssize_t nb, char *dp, const quoted_t * tab) {
|
||||
uint32_t mm;
|
||||
const char * ss = sp;
|
||||
const char * ds = dp;
|
||||
size_t cn = 0;
|
||||
uint8_t ch;
|
||||
|
||||
simd_copy:
|
||||
|
||||
|
|
|
|||
385
native/ryu_tab.h
385
native/ryu_tab.h
|
|
@ -1,385 +0,0 @@
|
|||
/* Copyright 2018 Ulf Adams.
|
||||
* Modifications copyright 2021 ByteDance Inc.
|
||||
*
|
||||
* The contents of this file may be used under the terms of the Apache License,
|
||||
* Version 2.0.
|
||||
*
|
||||
* (See accompanying file LICENSE-Apache or copy at
|
||||
* http: *www.apache.org/licenses/LICENSE-2.0)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE-Boost or copy at
|
||||
* https: *www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this software
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied.
|
||||
*/
|
||||
#ifndef RYU_TAB_H
|
||||
#define RYU_TAB_H
|
||||
|
||||
/* These tables are generated by PrintDoubleLookupTable */
|
||||
#define DOUBLE_POW5_INV_BITCOUNT 125
|
||||
#define DOUBLE_POW5_BITCOUNT 125
|
||||
|
||||
#define DOUBLE_POW5_INV_TABLE_SIZE 342
|
||||
#define DOUBLE_POW5_TABLE_SIZE 326
|
||||
|
||||
/* A table of all two-digit numbers. This is used to speed up decimal digit
|
||||
* generation by copying pairs of digits into the final output.
|
||||
*/
|
||||
static const char DIG_TAB[200] = {
|
||||
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
|
||||
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
|
||||
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
|
||||
'3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
|
||||
'4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
|
||||
'5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
|
||||
'6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
|
||||
'7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
|
||||
'8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
|
||||
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
|
||||
};
|
||||
|
||||
static const uint64_t DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] = {
|
||||
{ 1u, 2305843009213693952u }, { 11068046444225730970u, 1844674407370955161u },
|
||||
{ 5165088340638674453u, 1475739525896764129u }, { 7821419487252849886u, 1180591620717411303u },
|
||||
{ 8824922364862649494u, 1888946593147858085u }, { 7059937891890119595u, 1511157274518286468u },
|
||||
{ 13026647942995916322u, 1208925819614629174u }, { 9774590264567735146u, 1934281311383406679u },
|
||||
{ 11509021026396098440u, 1547425049106725343u }, { 16585914450600699399u, 1237940039285380274u },
|
||||
{ 15469416676735388068u, 1980704062856608439u }, { 16064882156130220778u, 1584563250285286751u },
|
||||
{ 9162556910162266299u, 1267650600228229401u }, { 7281393426775805432u, 2028240960365167042u },
|
||||
{ 16893161185646375315u, 1622592768292133633u }, { 2446482504291369283u, 1298074214633706907u },
|
||||
{ 7603720821608101175u, 2076918743413931051u }, { 2393627842544570617u, 1661534994731144841u },
|
||||
{ 16672297533003297786u, 1329227995784915872u }, { 11918280793837635165u, 2126764793255865396u },
|
||||
{ 5845275820328197809u, 1701411834604692317u }, { 15744267100488289217u, 1361129467683753853u },
|
||||
{ 3054734472329800808u, 2177807148294006166u }, { 17201182836831481939u, 1742245718635204932u },
|
||||
{ 6382248639981364905u, 1393796574908163946u }, { 2832900194486363201u, 2230074519853062314u },
|
||||
{ 5955668970331000884u, 1784059615882449851u }, { 1075186361522890384u, 1427247692705959881u },
|
||||
{ 12788344622662355584u, 2283596308329535809u }, { 13920024512871794791u, 1826877046663628647u },
|
||||
{ 3757321980813615186u, 1461501637330902918u }, { 10384555214134712795u, 1169201309864722334u },
|
||||
{ 5547241898389809503u, 1870722095783555735u }, { 4437793518711847602u, 1496577676626844588u },
|
||||
{ 10928932444453298728u, 1197262141301475670u }, { 17486291911125277965u, 1915619426082361072u },
|
||||
{ 6610335899416401726u, 1532495540865888858u }, { 12666966349016942027u, 1225996432692711086u },
|
||||
{ 12888448528943286597u, 1961594292308337738u }, { 17689456452638449924u, 1569275433846670190u },
|
||||
{ 14151565162110759939u, 1255420347077336152u }, { 7885109000409574610u, 2008672555323737844u },
|
||||
{ 9997436015069570011u, 1606938044258990275u }, { 7997948812055656009u, 1285550435407192220u },
|
||||
{ 12796718099289049614u, 2056880696651507552u }, { 2858676849947419045u, 1645504557321206042u },
|
||||
{ 13354987924183666206u, 1316403645856964833u }, { 17678631863951955605u, 2106245833371143733u },
|
||||
{ 3074859046935833515u, 1684996666696914987u }, { 13527933681774397782u, 1347997333357531989u },
|
||||
{ 10576647446613305481u, 2156795733372051183u }, { 15840015586774465031u, 1725436586697640946u },
|
||||
{ 8982663654677661702u, 1380349269358112757u }, { 18061610662226169046u, 2208558830972980411u },
|
||||
{ 10759939715039024913u, 1766847064778384329u }, { 12297300586773130254u, 1413477651822707463u },
|
||||
{ 15986332124095098083u, 2261564242916331941u }, { 9099716884534168143u, 1809251394333065553u },
|
||||
{ 14658471137111155161u, 1447401115466452442u }, { 4348079280205103483u, 1157920892373161954u },
|
||||
{ 14335624477811986218u, 1852673427797059126u }, { 7779150767507678651u, 1482138742237647301u },
|
||||
{ 2533971799264232598u, 1185710993790117841u }, { 15122401323048503126u, 1897137590064188545u },
|
||||
{ 12097921058438802501u, 1517710072051350836u }, { 5988988032009131678u, 1214168057641080669u },
|
||||
{ 16961078480698431330u, 1942668892225729070u }, { 13568862784558745064u, 1554135113780583256u },
|
||||
{ 7165741412905085728u, 1243308091024466605u }, { 11465186260648137165u, 1989292945639146568u },
|
||||
{ 16550846638002330379u, 1591434356511317254u }, { 16930026125143774626u, 1273147485209053803u },
|
||||
{ 4951948911778577463u, 2037035976334486086u }, { 272210314680951647u, 1629628781067588869u },
|
||||
{ 3907117066486671641u, 1303703024854071095u }, { 6251387306378674625u, 2085924839766513752u },
|
||||
{ 16069156289328670670u, 1668739871813211001u }, { 9165976216721026213u, 1334991897450568801u },
|
||||
{ 7286864317269821294u, 2135987035920910082u }, { 16897537898041588005u, 1708789628736728065u },
|
||||
{ 13518030318433270404u, 1367031702989382452u }, { 6871453250525591353u, 2187250724783011924u },
|
||||
{ 9186511415162383406u, 1749800579826409539u }, { 11038557946871817048u, 1399840463861127631u },
|
||||
{ 10282995085511086630u, 2239744742177804210u }, { 8226396068408869304u, 1791795793742243368u },
|
||||
{ 13959814484210916090u, 1433436634993794694u }, { 11267656730511734774u, 2293498615990071511u },
|
||||
{ 5324776569667477496u, 1834798892792057209u }, { 7949170070475892320u, 1467839114233645767u },
|
||||
{ 17427382500606444826u, 1174271291386916613u }, { 5747719112518849781u, 1878834066219066582u },
|
||||
{ 15666221734240810795u, 1503067252975253265u }, { 12532977387392648636u, 1202453802380202612u },
|
||||
{ 5295368560860596524u, 1923926083808324180u }, { 4236294848688477220u, 1539140867046659344u },
|
||||
{ 7078384693692692099u, 1231312693637327475u }, { 11325415509908307358u, 1970100309819723960u },
|
||||
{ 9060332407926645887u, 1576080247855779168u }, { 14626963555825137356u, 1260864198284623334u },
|
||||
{ 12335095245094488799u, 2017382717255397335u }, { 9868076196075591040u, 1613906173804317868u },
|
||||
{ 15273158586344293478u, 1291124939043454294u }, { 13369007293925138595u, 2065799902469526871u },
|
||||
{ 7005857020398200553u, 1652639921975621497u }, { 16672732060544291412u, 1322111937580497197u },
|
||||
{ 11918976037903224966u, 2115379100128795516u }, { 5845832015580669650u, 1692303280103036413u },
|
||||
{ 12055363241948356366u, 1353842624082429130u }, { 841837113407818570u, 2166148198531886609u },
|
||||
{ 4362818505468165179u, 1732918558825509287u }, { 14558301248600263113u, 1386334847060407429u },
|
||||
{ 12225235553534690011u, 2218135755296651887u }, { 2401490813343931363u, 1774508604237321510u },
|
||||
{ 1921192650675145090u, 1419606883389857208u }, { 17831303500047873437u, 2271371013423771532u },
|
||||
{ 6886345170554478103u, 1817096810739017226u }, { 1819727321701672159u, 1453677448591213781u },
|
||||
{ 16213177116328979020u, 1162941958872971024u }, { 14873036941900635463u, 1860707134196753639u },
|
||||
{ 15587778368262418694u, 1488565707357402911u }, { 8780873879868024632u, 1190852565885922329u },
|
||||
{ 2981351763563108441u, 1905364105417475727u }, { 13453127855076217722u, 1524291284333980581u },
|
||||
{ 7073153469319063855u, 1219433027467184465u }, { 11317045550910502167u, 1951092843947495144u },
|
||||
{ 12742985255470312057u, 1560874275157996115u }, { 10194388204376249646u, 1248699420126396892u },
|
||||
{ 1553625868034358140u, 1997919072202235028u }, { 8621598323911307159u, 1598335257761788022u },
|
||||
{ 17965325103354776697u, 1278668206209430417u }, { 13987124906400001422u, 2045869129935088668u },
|
||||
{ 121653480894270168u, 1636695303948070935u }, { 97322784715416134u, 1309356243158456748u },
|
||||
{ 14913111714512307107u, 2094969989053530796u }, { 8241140556867935363u, 1675975991242824637u },
|
||||
{ 17660958889720079260u, 1340780792994259709u }, { 17189487779326395846u, 2145249268790815535u },
|
||||
{ 13751590223461116677u, 1716199415032652428u }, { 18379969808252713988u, 1372959532026121942u },
|
||||
{ 14650556434236701088u, 2196735251241795108u }, { 652398703163629901u, 1757388200993436087u },
|
||||
{ 11589965406756634890u, 1405910560794748869u }, { 7475898206584884855u, 2249456897271598191u },
|
||||
{ 2291369750525997561u, 1799565517817278553u }, { 9211793429904618695u, 1439652414253822842u },
|
||||
{ 18428218302589300235u, 2303443862806116547u }, { 7363877012587619542u, 1842755090244893238u },
|
||||
{ 13269799239553916280u, 1474204072195914590u }, { 10615839391643133024u, 1179363257756731672u },
|
||||
{ 2227947767661371545u, 1886981212410770676u }, { 16539753473096738529u, 1509584969928616540u },
|
||||
{ 13231802778477390823u, 1207667975942893232u }, { 6413489186596184024u, 1932268761508629172u },
|
||||
{ 16198837793502678189u, 1545815009206903337u }, { 5580372605318321905u, 1236652007365522670u },
|
||||
{ 8928596168509315048u, 1978643211784836272u }, { 18210923379033183008u, 1582914569427869017u },
|
||||
{ 7190041073742725760u, 1266331655542295214u }, { 436019273762630246u, 2026130648867672343u },
|
||||
{ 7727513048493924843u, 1620904519094137874u }, { 9871359253537050198u, 1296723615275310299u },
|
||||
{ 4726128361433549347u, 2074757784440496479u }, { 7470251503888749801u, 1659806227552397183u },
|
||||
{ 13354898832594820487u, 1327844982041917746u }, { 13989140502667892133u, 2124551971267068394u },
|
||||
{ 14880661216876224029u, 1699641577013654715u }, { 11904528973500979224u, 1359713261610923772u },
|
||||
{ 4289851098633925465u, 2175541218577478036u }, { 18189276137874781665u, 1740432974861982428u },
|
||||
{ 3483374466074094362u, 1392346379889585943u }, { 1884050330976640656u, 2227754207823337509u },
|
||||
{ 5196589079523222848u, 1782203366258670007u }, { 15225317707844309248u, 1425762693006936005u },
|
||||
{ 5913764258841343181u, 2281220308811097609u }, { 8420360221814984868u, 1824976247048878087u },
|
||||
{ 17804334621677718864u, 1459980997639102469u }, { 17932816512084085415u, 1167984798111281975u },
|
||||
{ 10245762345624985047u, 1868775676978051161u }, { 4507261061758077715u, 1495020541582440929u },
|
||||
{ 7295157664148372495u, 1196016433265952743u }, { 7982903447895485668u, 1913626293225524389u },
|
||||
{ 10075671573058298858u, 1530901034580419511u }, { 4371188443704728763u, 1224720827664335609u },
|
||||
{ 14372599139411386667u, 1959553324262936974u }, { 15187428126271019657u, 1567642659410349579u },
|
||||
{ 15839291315758726049u, 1254114127528279663u }, { 3206773216762499739u, 2006582604045247462u },
|
||||
{ 13633465017635730761u, 1605266083236197969u }, { 14596120828850494932u, 1284212866588958375u },
|
||||
{ 4907049252451240275u, 2054740586542333401u }, { 236290587219081897u, 1643792469233866721u },
|
||||
{ 14946427728742906810u, 1315033975387093376u }, { 16535586736504830250u, 2104054360619349402u },
|
||||
{ 5849771759720043554u, 1683243488495479522u }, { 15747863852001765813u, 1346594790796383617u },
|
||||
{ 10439186904235184007u, 2154551665274213788u }, { 15730047152871967852u, 1723641332219371030u },
|
||||
{ 12584037722297574282u, 1378913065775496824u }, { 9066413911450387881u, 2206260905240794919u },
|
||||
{ 10942479943902220628u, 1765008724192635935u }, { 8753983955121776503u, 1412006979354108748u },
|
||||
{ 10317025513452932081u, 2259211166966573997u }, { 874922781278525018u, 1807368933573259198u },
|
||||
{ 8078635854506640661u, 1445895146858607358u }, { 13841606313089133175u, 1156716117486885886u },
|
||||
{ 14767872471458792434u, 1850745787979017418u }, { 746251532941302978u, 1480596630383213935u },
|
||||
{ 597001226353042382u, 1184477304306571148u }, { 15712597221132509104u, 1895163686890513836u },
|
||||
{ 8880728962164096960u, 1516130949512411069u }, { 10793931984473187891u, 1212904759609928855u },
|
||||
{ 17270291175157100626u, 1940647615375886168u }, { 2748186495899949531u, 1552518092300708935u },
|
||||
{ 2198549196719959625u, 1242014473840567148u }, { 18275073973719576693u, 1987223158144907436u },
|
||||
{ 10930710364233751031u, 1589778526515925949u }, { 12433917106128911148u, 1271822821212740759u },
|
||||
{ 8826220925580526867u, 2034916513940385215u }, { 7060976740464421494u, 1627933211152308172u },
|
||||
{ 16716827836597268165u, 1302346568921846537u }, { 11989529279587987770u, 2083754510274954460u },
|
||||
{ 9591623423670390216u, 1667003608219963568u }, { 15051996368420132820u, 1333602886575970854u },
|
||||
{ 13015147745246481542u, 2133764618521553367u }, { 3033420566713364587u, 1707011694817242694u },
|
||||
{ 6116085268112601993u, 1365609355853794155u }, { 9785736428980163188u, 2184974969366070648u },
|
||||
{ 15207286772667951197u, 1747979975492856518u }, { 1097782973908629988u, 1398383980394285215u },
|
||||
{ 1756452758253807981u, 2237414368630856344u }, { 5094511021344956708u, 1789931494904685075u },
|
||||
{ 4075608817075965366u, 1431945195923748060u }, { 6520974107321544586u, 2291112313477996896u },
|
||||
{ 1527430471115325346u, 1832889850782397517u }, { 12289990821117991246u, 1466311880625918013u },
|
||||
{ 17210690286378213644u, 1173049504500734410u }, { 9090360384495590213u, 1876879207201175057u },
|
||||
{ 18340334751822203140u, 1501503365760940045u }, { 14672267801457762512u, 1201202692608752036u },
|
||||
{ 16096930852848599373u, 1921924308174003258u }, { 1809498238053148529u, 1537539446539202607u },
|
||||
{ 12515645034668249793u, 1230031557231362085u }, { 1578287981759648052u, 1968050491570179337u },
|
||||
{ 12330676829633449412u, 1574440393256143469u }, { 13553890278448669853u, 1259552314604914775u },
|
||||
{ 3239480371808320148u, 2015283703367863641u }, { 17348979556414297411u, 1612226962694290912u },
|
||||
{ 6500486015647617283u, 1289781570155432730u }, { 10400777625036187652u, 2063650512248692368u },
|
||||
{ 15699319729512770768u, 1650920409798953894u }, { 16248804598352126938u, 1320736327839163115u },
|
||||
{ 7551343283653851484u, 2113178124542660985u }, { 6041074626923081187u, 1690542499634128788u },
|
||||
{ 12211557331022285596u, 1352433999707303030u }, { 1091747655926105338u, 2163894399531684849u },
|
||||
{ 4562746939482794594u, 1731115519625347879u }, { 7339546366328145998u, 1384892415700278303u },
|
||||
{ 8053925371383123274u, 2215827865120445285u }, { 6443140297106498619u, 1772662292096356228u },
|
||||
{ 12533209867169019542u, 1418129833677084982u }, { 5295740528502789974u, 2269007733883335972u },
|
||||
{ 15304638867027962949u, 1815206187106668777u }, { 4865013464138549713u, 1452164949685335022u },
|
||||
{ 14960057215536570740u, 1161731959748268017u }, { 9178696285890871890u, 1858771135597228828u },
|
||||
{ 14721654658196518159u, 1487016908477783062u }, { 4398626097073393881u, 1189613526782226450u },
|
||||
{ 7037801755317430209u, 1903381642851562320u }, { 5630241404253944167u, 1522705314281249856u },
|
||||
{ 814844308661245011u, 1218164251424999885u }, { 1303750893857992017u, 1949062802279999816u },
|
||||
{ 15800395974054034906u, 1559250241823999852u }, { 5261619149759407279u, 1247400193459199882u },
|
||||
{ 12107939454356961969u, 1995840309534719811u }, { 5997002748743659252u, 1596672247627775849u },
|
||||
{ 8486951013736837725u, 1277337798102220679u }, { 2511075177753209390u, 2043740476963553087u },
|
||||
{ 13076906586428298482u, 1634992381570842469u }, { 14150874083884549109u, 1307993905256673975u },
|
||||
{ 4194654460505726958u, 2092790248410678361u }, { 18113118827372222859u, 1674232198728542688u },
|
||||
{ 3422448617672047318u, 1339385758982834151u }, { 16543964232501006678u, 2143017214372534641u },
|
||||
{ 9545822571258895019u, 1714413771498027713u }, { 15015355686490936662u, 1371531017198422170u },
|
||||
{ 5577825024675947042u, 2194449627517475473u }, { 11840957649224578280u, 1755559702013980378u },
|
||||
{ 16851463748863483271u, 1404447761611184302u }, { 12204946739213931940u, 2247116418577894884u },
|
||||
{ 13453306206113055875u, 1797693134862315907u }, { 3383947335406624054u, 1438154507889852726u },
|
||||
{ 16482362180876329456u, 2301047212623764361u }, { 9496540929959153242u, 1840837770099011489u },
|
||||
{ 11286581558709232917u, 1472670216079209191u }, { 5339916432225476010u, 1178136172863367353u },
|
||||
{ 4854517476818851293u, 1885017876581387765u }, { 3883613981455081034u, 1508014301265110212u },
|
||||
{ 14174937629389795797u, 1206411441012088169u }, { 11611853762797942306u, 1930258305619341071u },
|
||||
{ 5600134195496443521u, 1544206644495472857u }, { 15548153800622885787u, 1235365315596378285u },
|
||||
{ 6430302007287065643u, 1976584504954205257u }, { 16212288050055383484u, 1581267603963364205u },
|
||||
{ 12969830440044306787u, 1265014083170691364u }, { 9683682259845159889u, 2024022533073106183u },
|
||||
{ 15125643437359948558u, 1619218026458484946u }, { 8411165935146048523u, 1295374421166787957u },
|
||||
{ 17147214310975587960u, 2072599073866860731u }, { 10028422634038560045u, 1658079259093488585u },
|
||||
{ 8022738107230848036u, 1326463407274790868u }, { 9147032156827446534u, 2122341451639665389u },
|
||||
{ 11006974540203867551u, 1697873161311732311u }, { 5116230817421183718u, 1358298529049385849u },
|
||||
{ 15564666937357714594u, 2173277646479017358u }, { 1383687105660440706u, 1738622117183213887u },
|
||||
{ 12174996128754083534u, 1390897693746571109u }, { 8411947361780802685u, 2225436309994513775u },
|
||||
{ 6729557889424642148u, 1780349047995611020u }, { 5383646311539713719u, 1424279238396488816u },
|
||||
{ 1235136468979721303u, 2278846781434382106u }, { 15745504434151418335u, 1823077425147505684u },
|
||||
{ 16285752362063044992u, 1458461940118004547u }, { 5649904260166615347u, 1166769552094403638u },
|
||||
{ 5350498001524674232u, 1866831283351045821u }, { 591049586477829062u, 1493465026680836657u },
|
||||
{ 11540886113407994219u, 1194772021344669325u }, { 18673707743239135u, 1911635234151470921u },
|
||||
{ 14772334225162232601u, 1529308187321176736u }, { 8128518565387875758u, 1223446549856941389u },
|
||||
{ 1937583260394870242u, 1957514479771106223u }, { 8928764237799716840u, 1566011583816884978u },
|
||||
{ 14521709019723594119u, 1252809267053507982u }, { 8477339172590109297u, 2004494827285612772u },
|
||||
{ 17849917782297818407u, 1603595861828490217u }, { 6901236596354434079u, 1282876689462792174u },
|
||||
{ 18420676183650915173u, 2052602703140467478u }, { 3668494502695001169u, 1642082162512373983u },
|
||||
{ 10313493231639821582u, 1313665730009899186u }, { 9122891541139893884u, 2101865168015838698u },
|
||||
{ 14677010862395735754u, 1681492134412670958u }, { 673562245690857633u, 1345193707530136767u }
|
||||
};
|
||||
|
||||
static const uint64_t DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] = {
|
||||
{ 0u, 1152921504606846976u }, { 0u, 1441151880758558720u },
|
||||
{ 0u, 1801439850948198400u }, { 0u, 2251799813685248000u },
|
||||
{ 0u, 1407374883553280000u }, { 0u, 1759218604441600000u },
|
||||
{ 0u, 2199023255552000000u }, { 0u, 1374389534720000000u },
|
||||
{ 0u, 1717986918400000000u }, { 0u, 2147483648000000000u },
|
||||
{ 0u, 1342177280000000000u }, { 0u, 1677721600000000000u },
|
||||
{ 0u, 2097152000000000000u }, { 0u, 1310720000000000000u },
|
||||
{ 0u, 1638400000000000000u }, { 0u, 2048000000000000000u },
|
||||
{ 0u, 1280000000000000000u }, { 0u, 1600000000000000000u },
|
||||
{ 0u, 2000000000000000000u }, { 0u, 1250000000000000000u },
|
||||
{ 0u, 1562500000000000000u }, { 0u, 1953125000000000000u },
|
||||
{ 0u, 1220703125000000000u }, { 0u, 1525878906250000000u },
|
||||
{ 0u, 1907348632812500000u }, { 0u, 1192092895507812500u },
|
||||
{ 0u, 1490116119384765625u }, { 4611686018427387904u, 1862645149230957031u },
|
||||
{ 9799832789158199296u, 1164153218269348144u }, { 12249790986447749120u, 1455191522836685180u },
|
||||
{ 15312238733059686400u, 1818989403545856475u }, { 14528612397897220096u, 2273736754432320594u },
|
||||
{ 13692068767113150464u, 1421085471520200371u }, { 12503399940464050176u, 1776356839400250464u },
|
||||
{ 15629249925580062720u, 2220446049250313080u }, { 9768281203487539200u, 1387778780781445675u },
|
||||
{ 7598665485932036096u, 1734723475976807094u }, { 274959820560269312u, 2168404344971008868u },
|
||||
{ 9395221924704944128u, 1355252715606880542u }, { 2520655369026404352u, 1694065894508600678u },
|
||||
{ 12374191248137781248u, 2117582368135750847u }, { 14651398557727195136u, 1323488980084844279u },
|
||||
{ 13702562178731606016u, 1654361225106055349u }, { 3293144668132343808u, 2067951531382569187u },
|
||||
{ 18199116482078572544u, 1292469707114105741u }, { 8913837547316051968u, 1615587133892632177u },
|
||||
{ 15753982952572452864u, 2019483917365790221u }, { 12152082354571476992u, 1262177448353618888u },
|
||||
{ 15190102943214346240u, 1577721810442023610u }, { 9764256642163156992u, 1972152263052529513u },
|
||||
{ 17631875447420442880u, 1232595164407830945u }, { 8204786253993389888u, 1540743955509788682u },
|
||||
{ 1032610780636961552u, 1925929944387235853u }, { 2951224747111794922u, 1203706215242022408u },
|
||||
{ 3689030933889743652u, 1504632769052528010u }, { 13834660704216955373u, 1880790961315660012u },
|
||||
{ 17870034976990372916u, 1175494350822287507u }, { 17725857702810578241u, 1469367938527859384u },
|
||||
{ 3710578054803671186u, 1836709923159824231u }, { 26536550077201078u, 2295887403949780289u },
|
||||
{ 11545800389866720434u, 1434929627468612680u }, { 14432250487333400542u, 1793662034335765850u },
|
||||
{ 8816941072311974870u, 2242077542919707313u }, { 17039803216263454053u, 1401298464324817070u },
|
||||
{ 12076381983474541759u, 1751623080406021338u }, { 5872105442488401391u, 2189528850507526673u },
|
||||
{ 15199280947623720629u, 1368455531567204170u }, { 9775729147674874978u, 1710569414459005213u },
|
||||
{ 16831347453020981627u, 2138211768073756516u }, { 1296220121283337709u, 1336382355046097823u },
|
||||
{ 15455333206886335848u, 1670477943807622278u }, { 10095794471753144002u, 2088097429759527848u },
|
||||
{ 6309871544845715001u, 1305060893599704905u }, { 12499025449484531656u, 1631326116999631131u },
|
||||
{ 11012095793428276666u, 2039157646249538914u }, { 11494245889320060820u, 1274473528905961821u },
|
||||
{ 532749306367912313u, 1593091911132452277u }, { 5277622651387278295u, 1991364888915565346u },
|
||||
{ 7910200175544436838u, 1244603055572228341u }, { 14499436237857933952u, 1555753819465285426u },
|
||||
{ 8900923260467641632u, 1944692274331606783u }, { 12480606065433357876u, 1215432671457254239u },
|
||||
{ 10989071563364309441u, 1519290839321567799u }, { 9124653435777998898u, 1899113549151959749u },
|
||||
{ 8008751406574943263u, 1186945968219974843u }, { 5399253239791291175u, 1483682460274968554u },
|
||||
{ 15972438586593889776u, 1854603075343710692u }, { 759402079766405302u, 1159126922089819183u },
|
||||
{ 14784310654990170340u, 1448908652612273978u }, { 9257016281882937117u, 1811135815765342473u },
|
||||
{ 16182956370781059300u, 2263919769706678091u }, { 7808504722524468110u, 1414949856066673807u },
|
||||
{ 5148944884728197234u, 1768687320083342259u }, { 1824495087482858639u, 2210859150104177824u },
|
||||
{ 1140309429676786649u, 1381786968815111140u }, { 1425386787095983311u, 1727233711018888925u },
|
||||
{ 6393419502297367043u, 2159042138773611156u }, { 13219259225790630210u, 1349401336733506972u },
|
||||
{ 16524074032238287762u, 1686751670916883715u }, { 16043406521870471799u, 2108439588646104644u },
|
||||
{ 803757039314269066u, 1317774742903815403u }, { 14839754354425000045u, 1647218428629769253u },
|
||||
{ 4714634887749086344u, 2059023035787211567u }, { 9864175832484260821u, 1286889397367007229u },
|
||||
{ 16941905809032713930u, 1608611746708759036u }, { 2730638187581340797u, 2010764683385948796u },
|
||||
{ 10930020904093113806u, 1256727927116217997u }, { 18274212148543780162u, 1570909908895272496u },
|
||||
{ 4396021111970173586u, 1963637386119090621u }, { 5053356204195052443u, 1227273366324431638u },
|
||||
{ 15540067292098591362u, 1534091707905539547u }, { 14813398096695851299u, 1917614634881924434u },
|
||||
{ 13870059828862294966u, 1198509146801202771u }, { 12725888767650480803u, 1498136433501503464u },
|
||||
{ 15907360959563101004u, 1872670541876879330u }, { 14553786618154326031u, 1170419088673049581u },
|
||||
{ 4357175217410743827u, 1463023860841311977u }, { 10058155040190817688u, 1828779826051639971u },
|
||||
{ 7961007781811134206u, 2285974782564549964u }, { 14199001900486734687u, 1428734239102843727u },
|
||||
{ 13137066357181030455u, 1785917798878554659u }, { 11809646928048900164u, 2232397248598193324u },
|
||||
{ 16604401366885338411u, 1395248280373870827u }, { 16143815690179285109u, 1744060350467338534u },
|
||||
{ 10956397575869330579u, 2180075438084173168u }, { 6847748484918331612u, 1362547148802608230u },
|
||||
{ 17783057643002690323u, 1703183936003260287u }, { 17617136035325974999u, 2128979920004075359u },
|
||||
{ 17928239049719816230u, 1330612450002547099u }, { 17798612793722382384u, 1663265562503183874u },
|
||||
{ 13024893955298202172u, 2079081953128979843u }, { 5834715712847682405u, 1299426220705612402u },
|
||||
{ 16516766677914378815u, 1624282775882015502u }, { 11422586310538197711u, 2030353469852519378u },
|
||||
{ 11750802462513761473u, 1268970918657824611u }, { 10076817059714813937u, 1586213648322280764u },
|
||||
{ 12596021324643517422u, 1982767060402850955u }, { 5566670318688504437u, 1239229412751781847u },
|
||||
{ 2346651879933242642u, 1549036765939727309u }, { 7545000868343941206u, 1936295957424659136u },
|
||||
{ 4715625542714963254u, 1210184973390411960u }, { 5894531928393704067u, 1512731216738014950u },
|
||||
{ 16591536947346905892u, 1890914020922518687u }, { 17287239619732898039u, 1181821263076574179u },
|
||||
{ 16997363506238734644u, 1477276578845717724u }, { 2799960309088866689u, 1846595723557147156u },
|
||||
{ 10973347230035317489u, 1154122327223216972u }, { 13716684037544146861u, 1442652909029021215u },
|
||||
{ 12534169028502795672u, 1803316136286276519u }, { 11056025267201106687u, 2254145170357845649u },
|
||||
{ 18439230838069161439u, 1408840731473653530u }, { 13825666510731675991u, 1761050914342066913u },
|
||||
{ 3447025083132431277u, 2201313642927583642u }, { 6766076695385157452u, 1375821026829739776u },
|
||||
{ 8457595869231446815u, 1719776283537174720u }, { 10571994836539308519u, 2149720354421468400u },
|
||||
{ 6607496772837067824u, 1343575221513417750u }, { 17482743002901110588u, 1679469026891772187u },
|
||||
{ 17241742735199000331u, 2099336283614715234u }, { 15387775227926763111u, 1312085177259197021u },
|
||||
{ 5399660979626290177u, 1640106471573996277u }, { 11361262242960250625u, 2050133089467495346u },
|
||||
{ 11712474920277544544u, 1281333180917184591u }, { 10028907631919542777u, 1601666476146480739u },
|
||||
{ 7924448521472040567u, 2002083095183100924u }, { 14176152362774801162u, 1251301934489438077u },
|
||||
{ 3885132398186337741u, 1564127418111797597u }, { 9468101516160310080u, 1955159272639746996u },
|
||||
{ 15140935484454969608u, 1221974545399841872u }, { 479425281859160394u, 1527468181749802341u },
|
||||
{ 5210967620751338397u, 1909335227187252926u }, { 17091912818251750210u, 1193334516992033078u },
|
||||
{ 12141518985959911954u, 1491668146240041348u }, { 15176898732449889943u, 1864585182800051685u },
|
||||
{ 11791404716994875166u, 1165365739250032303u }, { 10127569877816206054u, 1456707174062540379u },
|
||||
{ 8047776328842869663u, 1820883967578175474u }, { 836348374198811271u, 2276104959472719343u },
|
||||
{ 7440246761515338900u, 1422565599670449589u }, { 13911994470321561530u, 1778206999588061986u },
|
||||
{ 8166621051047176104u, 2222758749485077483u }, { 2798295147690791113u, 1389224218428173427u },
|
||||
{ 17332926989895652603u, 1736530273035216783u }, { 17054472718942177850u, 2170662841294020979u },
|
||||
{ 8353202440125167204u, 1356664275808763112u }, { 10441503050156459005u, 1695830344760953890u },
|
||||
{ 3828506775840797949u, 2119787930951192363u }, { 86973725686804766u, 1324867456844495227u },
|
||||
{ 13943775212390669669u, 1656084321055619033u }, { 3594660960206173375u, 2070105401319523792u },
|
||||
{ 2246663100128858359u, 1293815875824702370u }, { 12031700912015848757u, 1617269844780877962u },
|
||||
{ 5816254103165035138u, 2021587305976097453u }, { 5941001823691840913u, 1263492066235060908u },
|
||||
{ 7426252279614801142u, 1579365082793826135u }, { 4671129331091113523u, 1974206353492282669u },
|
||||
{ 5225298841145639904u, 1233878970932676668u }, { 6531623551432049880u, 1542348713665845835u },
|
||||
{ 3552843420862674446u, 1927935892082307294u }, { 16055585193321335241u, 1204959932551442058u },
|
||||
{ 10846109454796893243u, 1506199915689302573u }, { 18169322836923504458u, 1882749894611628216u },
|
||||
{ 11355826773077190286u, 1176718684132267635u }, { 9583097447919099954u, 1470898355165334544u },
|
||||
{ 11978871809898874942u, 1838622943956668180u }, { 14973589762373593678u, 2298278679945835225u },
|
||||
{ 2440964573842414192u, 1436424174966147016u }, { 3051205717303017741u, 1795530218707683770u },
|
||||
{ 13037379183483547984u, 2244412773384604712u }, { 8148361989677217490u, 1402757983365377945u },
|
||||
{ 14797138505523909766u, 1753447479206722431u }, { 13884737113477499304u, 2191809349008403039u },
|
||||
{ 15595489723564518921u, 1369880843130251899u }, { 14882676136028260747u, 1712351053912814874u },
|
||||
{ 9379973133180550126u, 2140438817391018593u }, { 17391698254306313589u, 1337774260869386620u },
|
||||
{ 3292878744173340370u, 1672217826086733276u }, { 4116098430216675462u, 2090272282608416595u },
|
||||
{ 266718509671728212u, 1306420176630260372u }, { 333398137089660265u, 1633025220787825465u },
|
||||
{ 5028433689789463235u, 2041281525984781831u }, { 10060300083759496378u, 1275800953740488644u },
|
||||
{ 12575375104699370472u, 1594751192175610805u }, { 1884160825592049379u, 1993438990219513507u },
|
||||
{ 17318501580490888525u, 1245899368887195941u }, { 7813068920331446945u, 1557374211108994927u },
|
||||
{ 5154650131986920777u, 1946717763886243659u }, { 915813323278131534u, 1216698602428902287u },
|
||||
{ 14979824709379828129u, 1520873253036127858u }, { 9501408849870009354u, 1901091566295159823u },
|
||||
{ 12855909558809837702u, 1188182228934474889u }, { 2234828893230133415u, 1485227786168093612u },
|
||||
{ 2793536116537666769u, 1856534732710117015u }, { 8663489100477123587u, 1160334207943823134u },
|
||||
{ 1605989338741628675u, 1450417759929778918u }, { 11230858710281811652u, 1813022199912223647u },
|
||||
{ 9426887369424876662u, 2266277749890279559u }, { 12809333633531629769u, 1416423593681424724u },
|
||||
{ 16011667041914537212u, 1770529492101780905u }, { 6179525747111007803u, 2213161865127226132u },
|
||||
{ 13085575628799155685u, 1383226165704516332u }, { 16356969535998944606u, 1729032707130645415u },
|
||||
{ 15834525901571292854u, 2161290883913306769u }, { 2979049660840976177u, 1350806802445816731u },
|
||||
{ 17558870131333383934u, 1688508503057270913u }, { 8113529608884566205u, 2110635628821588642u },
|
||||
{ 9682642023980241782u, 1319147268013492901u }, { 16714988548402690132u, 1648934085016866126u },
|
||||
{ 11670363648648586857u, 2061167606271082658u }, { 11905663298832754689u, 1288229753919426661u },
|
||||
{ 1047021068258779650u, 1610287192399283327u }, { 15143834390605638274u, 2012858990499104158u },
|
||||
{ 4853210475701136017u, 1258036869061940099u }, { 1454827076199032118u, 1572546086327425124u },
|
||||
{ 1818533845248790147u, 1965682607909281405u }, { 3442426662494187794u, 1228551629943300878u },
|
||||
{ 13526405364972510550u, 1535689537429126097u }, { 3072948650933474476u, 1919611921786407622u },
|
||||
{ 15755650962115585259u, 1199757451116504763u }, { 15082877684217093670u, 1499696813895630954u },
|
||||
{ 9630225068416591280u, 1874621017369538693u }, { 8324733676974063502u, 1171638135855961683u },
|
||||
{ 5794231077790191473u, 1464547669819952104u }, { 7242788847237739342u, 1830684587274940130u },
|
||||
{ 18276858095901949986u, 2288355734093675162u }, { 16034722328366106645u, 1430222333808546976u },
|
||||
{ 1596658836748081690u, 1787777917260683721u }, { 6607509564362490017u, 2234722396575854651u },
|
||||
{ 1823850468512862308u, 1396701497859909157u }, { 6891499104068465790u, 1745876872324886446u },
|
||||
{ 17837745916940358045u, 2182346090406108057u }, { 4231062170446641922u, 1363966306503817536u },
|
||||
{ 5288827713058302403u, 1704957883129771920u }, { 6611034641322878003u, 2131197353912214900u },
|
||||
{ 13355268687681574560u, 1331998346195134312u }, { 16694085859601968200u, 1664997932743917890u },
|
||||
{ 11644235287647684442u, 2081247415929897363u }, { 4971804045566108824u, 1300779634956185852u },
|
||||
{ 6214755056957636030u, 1625974543695232315u }, { 3156757802769657134u, 2032468179619040394u },
|
||||
{ 6584659645158423613u, 1270292612261900246u }, { 17454196593302805324u, 1587865765327375307u },
|
||||
{ 17206059723201118751u, 1984832206659219134u }, { 6142101308573311315u, 1240520129162011959u },
|
||||
{ 3065940617289251240u, 1550650161452514949u }, { 8444111790038951954u, 1938312701815643686u },
|
||||
{ 665883850346957067u, 1211445438634777304u }, { 832354812933696334u, 1514306798293471630u },
|
||||
{ 10263815553021896226u, 1892883497866839537u }, { 17944099766707154901u, 1183052186166774710u },
|
||||
{ 13206752671529167818u, 1478815232708468388u }, { 16508440839411459773u, 1848519040885585485u },
|
||||
{ 12623618533845856310u, 1155324400553490928u }, { 15779523167307320387u, 1444155500691863660u },
|
||||
{ 1277659885424598868u, 1805194375864829576u }, { 1597074856780748586u, 2256492969831036970u },
|
||||
{ 5609857803915355770u, 1410308106144398106u }, { 16235694291748970521u, 1762885132680497632u },
|
||||
{ 1847873790976661535u, 2203606415850622041u }, { 12684136165428883219u, 1377254009906638775u },
|
||||
{ 11243484188358716120u, 1721567512383298469u }, { 219297180166231438u, 2151959390479123087u },
|
||||
{ 7054589765244976505u, 1344974619049451929u }, { 13429923224983608535u, 1681218273811814911u },
|
||||
{ 12175718012802122765u, 2101522842264768639u }, { 14527352785642408584u, 1313451776415480399u },
|
||||
{ 13547504963625622826u, 1641814720519350499u }, { 12322695186104640628u, 2052268400649188124u },
|
||||
{ 16925056528170176201u, 1282667750405742577u }, { 7321262604930556539u, 1603334688007178222u },
|
||||
{ 18374950293017971482u, 2004168360008972777u }, { 4566814905495150320u, 1252605225005607986u },
|
||||
{ 14931890668723713708u, 1565756531257009982u }, { 9441491299049866327u, 1957195664071262478u },
|
||||
{ 1289246043478778550u, 1223247290044539049u }, { 6223243572775861092u, 1529059112555673811u },
|
||||
{ 3167368447542438461u, 1911323890694592264u }, { 1979605279714024038u, 1194577431684120165u },
|
||||
{ 7086192618069917952u, 1493221789605150206u }, { 18081112809442173248u, 1866527237006437757u },
|
||||
{ 13606538515115052232u, 1166579523129023598u }, { 7784801107039039482u, 1458224403911279498u },
|
||||
{ 507629346944023544u, 1822780504889099373u }, { 5246222702107417334u, 2278475631111374216u },
|
||||
{ 3278889188817135834u, 1424047269444608885u }, { 8710297504448807696u, 1780059086805761106u }
|
||||
};
|
||||
|
||||
#endif // RYU_TAB_H
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include "native.h"
|
||||
#include "utf8.h"
|
||||
#include "test/xprintf.h"
|
||||
|
||||
static const uint64_t ODD_MASK = 0xaaaaaaaaaaaaaaaa;
|
||||
static const uint64_t EVEN_MASK = 0x5555555555555555;
|
||||
|
|
|
|||
695
native/tab.h
Normal file
695
native/tab.h
Normal file
|
|
@ -0,0 +1,695 @@
|
|||
/*
|
||||
* Copyright 2022 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef TAB_H
|
||||
#define TAB_H
|
||||
|
||||
#include "test/xassert.h"
|
||||
|
||||
struct uint64x2 {
|
||||
uint64_t hi;
|
||||
uint64_t lo;
|
||||
};
|
||||
typedef struct uint64x2 uint64x2;
|
||||
|
||||
static const char Digits[200] = {
|
||||
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
|
||||
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
|
||||
'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
|
||||
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
|
||||
'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
|
||||
'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
|
||||
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
|
||||
'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
|
||||
'8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
|
||||
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9',
|
||||
};
|
||||
|
||||
static inline bool is_div_pow2(uint64_t val, int32_t e) {
|
||||
xassert(e >= 0 && e <= 63);
|
||||
uint64_t mask = (1ull << e) - 1;
|
||||
return (val & mask) == 0;
|
||||
}
|
||||
|
||||
static inline char* utoa2(char* p, uint32_t val) {
|
||||
p[0] = Digits[val];
|
||||
p[1] = Digits[val + 1];
|
||||
return p + 2;
|
||||
}
|
||||
|
||||
static inline void copy_two_digs(char* dst, const char* src) {
|
||||
*(dst) = *(src);
|
||||
*(dst + 1) = *(src + 1);
|
||||
}
|
||||
|
||||
static inline const uint64x2 pow10_ceil_sig(int32_t k) {
|
||||
// There are unique beta and r such that 10^k = beta 2^r and
|
||||
// 2^127 <= beta < 2^128, namely r = floor(log_2 10^k) - 127 and
|
||||
// beta = 2^-r 10^k.
|
||||
// Let g = ceil(beta), so (g-1) 2^r < 10^k <= g 2^r, with the latter
|
||||
// value being a pretty good overestimate for 10^k.
|
||||
|
||||
// NB: Since for all the required exponents k, we have g < 2^128,
|
||||
// all constants can be stored in 128-bit integers.
|
||||
// Reference from:
|
||||
// https://github.com/abolz/Drachennest/blob/master/src/schubfach_64.cc#L151
|
||||
|
||||
#define KMIN -292
|
||||
#define KMAX 324
|
||||
static const uint64x2 g[KMAX - KMIN + 1] = {
|
||||
{0xFF77B1FCBEBCDC4F, 0x25E8E89C13BB0F7B}, // -292
|
||||
{0x9FAACF3DF73609B1, 0x77B191618C54E9AD}, // -291
|
||||
{0xC795830D75038C1D, 0xD59DF5B9EF6A2418}, // -290
|
||||
{0xF97AE3D0D2446F25, 0x4B0573286B44AD1E}, // -289
|
||||
{0x9BECCE62836AC577, 0x4EE367F9430AEC33}, // -288
|
||||
{0xC2E801FB244576D5, 0x229C41F793CDA740}, // -287
|
||||
{0xF3A20279ED56D48A, 0x6B43527578C11110}, // -286
|
||||
{0x9845418C345644D6, 0x830A13896B78AAAA}, // -285
|
||||
{0xBE5691EF416BD60C, 0x23CC986BC656D554}, // -284
|
||||
{0xEDEC366B11C6CB8F, 0x2CBFBE86B7EC8AA9}, // -283
|
||||
{0x94B3A202EB1C3F39, 0x7BF7D71432F3D6AA}, // -282
|
||||
{0xB9E08A83A5E34F07, 0xDAF5CCD93FB0CC54}, // -281
|
||||
{0xE858AD248F5C22C9, 0xD1B3400F8F9CFF69}, // -280
|
||||
{0x91376C36D99995BE, 0x23100809B9C21FA2}, // -279
|
||||
{0xB58547448FFFFB2D, 0xABD40A0C2832A78B}, // -278
|
||||
{0xE2E69915B3FFF9F9, 0x16C90C8F323F516D}, // -277
|
||||
{0x8DD01FAD907FFC3B, 0xAE3DA7D97F6792E4}, // -276
|
||||
{0xB1442798F49FFB4A, 0x99CD11CFDF41779D}, // -275
|
||||
{0xDD95317F31C7FA1D, 0x40405643D711D584}, // -274
|
||||
{0x8A7D3EEF7F1CFC52, 0x482835EA666B2573}, // -273
|
||||
{0xAD1C8EAB5EE43B66, 0xDA3243650005EED0}, // -272
|
||||
{0xD863B256369D4A40, 0x90BED43E40076A83}, // -271
|
||||
{0x873E4F75E2224E68, 0x5A7744A6E804A292}, // -270
|
||||
{0xA90DE3535AAAE202, 0x711515D0A205CB37}, // -269
|
||||
{0xD3515C2831559A83, 0x0D5A5B44CA873E04}, // -268
|
||||
{0x8412D9991ED58091, 0xE858790AFE9486C3}, // -267
|
||||
{0xA5178FFF668AE0B6, 0x626E974DBE39A873}, // -266
|
||||
{0xCE5D73FF402D98E3, 0xFB0A3D212DC81290}, // -265
|
||||
{0x80FA687F881C7F8E, 0x7CE66634BC9D0B9A}, // -264
|
||||
{0xA139029F6A239F72, 0x1C1FFFC1EBC44E81}, // -263
|
||||
{0xC987434744AC874E, 0xA327FFB266B56221}, // -262
|
||||
{0xFBE9141915D7A922, 0x4BF1FF9F0062BAA9}, // -261
|
||||
{0x9D71AC8FADA6C9B5, 0x6F773FC3603DB4AA}, // -260
|
||||
{0xC4CE17B399107C22, 0xCB550FB4384D21D4}, // -259
|
||||
{0xF6019DA07F549B2B, 0x7E2A53A146606A49}, // -258
|
||||
{0x99C102844F94E0FB, 0x2EDA7444CBFC426E}, // -257
|
||||
{0xC0314325637A1939, 0xFA911155FEFB5309}, // -256
|
||||
{0xF03D93EEBC589F88, 0x793555AB7EBA27CB}, // -255
|
||||
{0x96267C7535B763B5, 0x4BC1558B2F3458DF}, // -254
|
||||
{0xBBB01B9283253CA2, 0x9EB1AAEDFB016F17}, // -253
|
||||
{0xEA9C227723EE8BCB, 0x465E15A979C1CADD}, // -252
|
||||
{0x92A1958A7675175F, 0x0BFACD89EC191ECA}, // -251
|
||||
{0xB749FAED14125D36, 0xCEF980EC671F667C}, // -250
|
||||
{0xE51C79A85916F484, 0x82B7E12780E7401B}, // -249
|
||||
{0x8F31CC0937AE58D2, 0xD1B2ECB8B0908811}, // -248
|
||||
{0xB2FE3F0B8599EF07, 0x861FA7E6DCB4AA16}, // -247
|
||||
{0xDFBDCECE67006AC9, 0x67A791E093E1D49B}, // -246
|
||||
{0x8BD6A141006042BD, 0xE0C8BB2C5C6D24E1}, // -245
|
||||
{0xAECC49914078536D, 0x58FAE9F773886E19}, // -244
|
||||
{0xDA7F5BF590966848, 0xAF39A475506A899F}, // -243
|
||||
{0x888F99797A5E012D, 0x6D8406C952429604}, // -242
|
||||
{0xAAB37FD7D8F58178, 0xC8E5087BA6D33B84}, // -241
|
||||
{0xD5605FCDCF32E1D6, 0xFB1E4A9A90880A65}, // -240
|
||||
{0x855C3BE0A17FCD26, 0x5CF2EEA09A550680}, // -239
|
||||
{0xA6B34AD8C9DFC06F, 0xF42FAA48C0EA481F}, // -238
|
||||
{0xD0601D8EFC57B08B, 0xF13B94DAF124DA27}, // -237
|
||||
{0x823C12795DB6CE57, 0x76C53D08D6B70859}, // -236
|
||||
{0xA2CB1717B52481ED, 0x54768C4B0C64CA6F}, // -235
|
||||
{0xCB7DDCDDA26DA268, 0xA9942F5DCF7DFD0A}, // -234
|
||||
{0xFE5D54150B090B02, 0xD3F93B35435D7C4D}, // -233
|
||||
{0x9EFA548D26E5A6E1, 0xC47BC5014A1A6DB0}, // -232
|
||||
{0xC6B8E9B0709F109A, 0x359AB6419CA1091C}, // -231
|
||||
{0xF867241C8CC6D4C0, 0xC30163D203C94B63}, // -230
|
||||
{0x9B407691D7FC44F8, 0x79E0DE63425DCF1E}, // -229
|
||||
{0xC21094364DFB5636, 0x985915FC12F542E5}, // -228
|
||||
{0xF294B943E17A2BC4, 0x3E6F5B7B17B2939E}, // -227
|
||||
{0x979CF3CA6CEC5B5A, 0xA705992CEECF9C43}, // -226
|
||||
{0xBD8430BD08277231, 0x50C6FF782A838354}, // -225
|
||||
{0xECE53CEC4A314EBD, 0xA4F8BF5635246429}, // -224
|
||||
{0x940F4613AE5ED136, 0x871B7795E136BE9A}, // -223
|
||||
{0xB913179899F68584, 0x28E2557B59846E40}, // -222
|
||||
{0xE757DD7EC07426E5, 0x331AEADA2FE589D0}, // -221
|
||||
{0x9096EA6F3848984F, 0x3FF0D2C85DEF7622}, // -220
|
||||
{0xB4BCA50B065ABE63, 0x0FED077A756B53AA}, // -219
|
||||
{0xE1EBCE4DC7F16DFB, 0xD3E8495912C62895}, // -218
|
||||
{0x8D3360F09CF6E4BD, 0x64712DD7ABBBD95D}, // -217
|
||||
{0xB080392CC4349DEC, 0xBD8D794D96AACFB4}, // -216
|
||||
{0xDCA04777F541C567, 0xECF0D7A0FC5583A1}, // -215
|
||||
{0x89E42CAAF9491B60, 0xF41686C49DB57245}, // -214
|
||||
{0xAC5D37D5B79B6239, 0x311C2875C522CED6}, // -213
|
||||
{0xD77485CB25823AC7, 0x7D633293366B828C}, // -212
|
||||
{0x86A8D39EF77164BC, 0xAE5DFF9C02033198}, // -211
|
||||
{0xA8530886B54DBDEB, 0xD9F57F830283FDFD}, // -210
|
||||
{0xD267CAA862A12D66, 0xD072DF63C324FD7C}, // -209
|
||||
{0x8380DEA93DA4BC60, 0x4247CB9E59F71E6E}, // -208
|
||||
{0xA46116538D0DEB78, 0x52D9BE85F074E609}, // -207
|
||||
{0xCD795BE870516656, 0x67902E276C921F8C}, // -206
|
||||
{0x806BD9714632DFF6, 0x00BA1CD8A3DB53B7}, // -205
|
||||
{0xA086CFCD97BF97F3, 0x80E8A40ECCD228A5}, // -204
|
||||
{0xC8A883C0FDAF7DF0, 0x6122CD128006B2CE}, // -203
|
||||
{0xFAD2A4B13D1B5D6C, 0x796B805720085F82}, // -202
|
||||
{0x9CC3A6EEC6311A63, 0xCBE3303674053BB1}, // -201
|
||||
{0xC3F490AA77BD60FC, 0xBEDBFC4411068A9D}, // -200
|
||||
{0xF4F1B4D515ACB93B, 0xEE92FB5515482D45}, // -199
|
||||
{0x991711052D8BF3C5, 0x751BDD152D4D1C4B}, // -198
|
||||
{0xBF5CD54678EEF0B6, 0xD262D45A78A0635E}, // -197
|
||||
{0xEF340A98172AACE4, 0x86FB897116C87C35}, // -196
|
||||
{0x9580869F0E7AAC0E, 0xD45D35E6AE3D4DA1}, // -195
|
||||
{0xBAE0A846D2195712, 0x8974836059CCA10A}, // -194
|
||||
{0xE998D258869FACD7, 0x2BD1A438703FC94C}, // -193
|
||||
{0x91FF83775423CC06, 0x7B6306A34627DDD0}, // -192
|
||||
{0xB67F6455292CBF08, 0x1A3BC84C17B1D543}, // -191
|
||||
{0xE41F3D6A7377EECA, 0x20CABA5F1D9E4A94}, // -190
|
||||
{0x8E938662882AF53E, 0x547EB47B7282EE9D}, // -189
|
||||
{0xB23867FB2A35B28D, 0xE99E619A4F23AA44}, // -188
|
||||
{0xDEC681F9F4C31F31, 0x6405FA00E2EC94D5}, // -187
|
||||
{0x8B3C113C38F9F37E, 0xDE83BC408DD3DD05}, // -186
|
||||
{0xAE0B158B4738705E, 0x9624AB50B148D446}, // -185
|
||||
{0xD98DDAEE19068C76, 0x3BADD624DD9B0958}, // -184
|
||||
{0x87F8A8D4CFA417C9, 0xE54CA5D70A80E5D7}, // -183
|
||||
{0xA9F6D30A038D1DBC, 0x5E9FCF4CCD211F4D}, // -182
|
||||
{0xD47487CC8470652B, 0x7647C32000696720}, // -181
|
||||
{0x84C8D4DFD2C63F3B, 0x29ECD9F40041E074}, // -180
|
||||
{0xA5FB0A17C777CF09, 0xF468107100525891}, // -179
|
||||
{0xCF79CC9DB955C2CC, 0x7182148D4066EEB5}, // -178
|
||||
{0x81AC1FE293D599BF, 0xC6F14CD848405531}, // -177
|
||||
{0xA21727DB38CB002F, 0xB8ADA00E5A506A7D}, // -176
|
||||
{0xCA9CF1D206FDC03B, 0xA6D90811F0E4851D}, // -175
|
||||
{0xFD442E4688BD304A, 0x908F4A166D1DA664}, // -174
|
||||
{0x9E4A9CEC15763E2E, 0x9A598E4E043287FF}, // -173
|
||||
{0xC5DD44271AD3CDBA, 0x40EFF1E1853F29FE}, // -172
|
||||
{0xF7549530E188C128, 0xD12BEE59E68EF47D}, // -171
|
||||
{0x9A94DD3E8CF578B9, 0x82BB74F8301958CF}, // -170
|
||||
{0xC13A148E3032D6E7, 0xE36A52363C1FAF02}, // -169
|
||||
{0xF18899B1BC3F8CA1, 0xDC44E6C3CB279AC2}, // -168
|
||||
{0x96F5600F15A7B7E5, 0x29AB103A5EF8C0BA}, // -167
|
||||
{0xBCB2B812DB11A5DE, 0x7415D448F6B6F0E8}, // -166
|
||||
{0xEBDF661791D60F56, 0x111B495B3464AD22}, // -165
|
||||
{0x936B9FCEBB25C995, 0xCAB10DD900BEEC35}, // -164
|
||||
{0xB84687C269EF3BFB, 0x3D5D514F40EEA743}, // -163
|
||||
{0xE65829B3046B0AFA, 0x0CB4A5A3112A5113}, // -162
|
||||
{0x8FF71A0FE2C2E6DC, 0x47F0E785EABA72AC}, // -161
|
||||
{0xB3F4E093DB73A093, 0x59ED216765690F57}, // -160
|
||||
{0xE0F218B8D25088B8, 0x306869C13EC3532D}, // -159
|
||||
{0x8C974F7383725573, 0x1E414218C73A13FC}, // -158
|
||||
{0xAFBD2350644EEACF, 0xE5D1929EF90898FB}, // -157
|
||||
{0xDBAC6C247D62A583, 0xDF45F746B74ABF3A}, // -156
|
||||
{0x894BC396CE5DA772, 0x6B8BBA8C328EB784}, // -155
|
||||
{0xAB9EB47C81F5114F, 0x066EA92F3F326565}, // -154
|
||||
{0xD686619BA27255A2, 0xC80A537B0EFEFEBE}, // -153
|
||||
{0x8613FD0145877585, 0xBD06742CE95F5F37}, // -152
|
||||
{0xA798FC4196E952E7, 0x2C48113823B73705}, // -151
|
||||
{0xD17F3B51FCA3A7A0, 0xF75A15862CA504C6}, // -150
|
||||
{0x82EF85133DE648C4, 0x9A984D73DBE722FC}, // -149
|
||||
{0xA3AB66580D5FDAF5, 0xC13E60D0D2E0EBBB}, // -148
|
||||
{0xCC963FEE10B7D1B3, 0x318DF905079926A9}, // -147
|
||||
{0xFFBBCFE994E5C61F, 0xFDF17746497F7053}, // -146
|
||||
{0x9FD561F1FD0F9BD3, 0xFEB6EA8BEDEFA634}, // -145
|
||||
{0xC7CABA6E7C5382C8, 0xFE64A52EE96B8FC1}, // -144
|
||||
{0xF9BD690A1B68637B, 0x3DFDCE7AA3C673B1}, // -143
|
||||
{0x9C1661A651213E2D, 0x06BEA10CA65C084F}, // -142
|
||||
{0xC31BFA0FE5698DB8, 0x486E494FCFF30A63}, // -141
|
||||
{0xF3E2F893DEC3F126, 0x5A89DBA3C3EFCCFB}, // -140
|
||||
{0x986DDB5C6B3A76B7, 0xF89629465A75E01D}, // -139
|
||||
{0xBE89523386091465, 0xF6BBB397F1135824}, // -138
|
||||
{0xEE2BA6C0678B597F, 0x746AA07DED582E2D}, // -137
|
||||
{0x94DB483840B717EF, 0xA8C2A44EB4571CDD}, // -136
|
||||
{0xBA121A4650E4DDEB, 0x92F34D62616CE414}, // -135
|
||||
{0xE896A0D7E51E1566, 0x77B020BAF9C81D18}, // -134
|
||||
{0x915E2486EF32CD60, 0x0ACE1474DC1D122F}, // -133
|
||||
{0xB5B5ADA8AAFF80B8, 0x0D819992132456BB}, // -132
|
||||
{0xE3231912D5BF60E6, 0x10E1FFF697ED6C6A}, // -131
|
||||
{0x8DF5EFABC5979C8F, 0xCA8D3FFA1EF463C2}, // -130
|
||||
{0xB1736B96B6FD83B3, 0xBD308FF8A6B17CB3}, // -129
|
||||
{0xDDD0467C64BCE4A0, 0xAC7CB3F6D05DDBDF}, // -128
|
||||
{0x8AA22C0DBEF60EE4, 0x6BCDF07A423AA96C}, // -127
|
||||
{0xAD4AB7112EB3929D, 0x86C16C98D2C953C7}, // -126
|
||||
{0xD89D64D57A607744, 0xE871C7BF077BA8B8}, // -125
|
||||
{0x87625F056C7C4A8B, 0x11471CD764AD4973}, // -124
|
||||
{0xA93AF6C6C79B5D2D, 0xD598E40D3DD89BD0}, // -123
|
||||
{0xD389B47879823479, 0x4AFF1D108D4EC2C4}, // -122
|
||||
{0x843610CB4BF160CB, 0xCEDF722A585139BB}, // -121
|
||||
{0xA54394FE1EEDB8FE, 0xC2974EB4EE658829}, // -120
|
||||
{0xCE947A3DA6A9273E, 0x733D226229FEEA33}, // -119
|
||||
{0x811CCC668829B887, 0x0806357D5A3F5260}, // -118
|
||||
{0xA163FF802A3426A8, 0xCA07C2DCB0CF26F8}, // -117
|
||||
{0xC9BCFF6034C13052, 0xFC89B393DD02F0B6}, // -116
|
||||
{0xFC2C3F3841F17C67, 0xBBAC2078D443ACE3}, // -115
|
||||
{0x9D9BA7832936EDC0, 0xD54B944B84AA4C0E}, // -114
|
||||
{0xC5029163F384A931, 0x0A9E795E65D4DF12}, // -113
|
||||
{0xF64335BCF065D37D, 0x4D4617B5FF4A16D6}, // -112
|
||||
{0x99EA0196163FA42E, 0x504BCED1BF8E4E46}, // -111
|
||||
{0xC06481FB9BCF8D39, 0xE45EC2862F71E1D7}, // -110
|
||||
{0xF07DA27A82C37088, 0x5D767327BB4E5A4D}, // -109
|
||||
{0x964E858C91BA2655, 0x3A6A07F8D510F870}, // -108
|
||||
{0xBBE226EFB628AFEA, 0x890489F70A55368C}, // -107
|
||||
{0xEADAB0ABA3B2DBE5, 0x2B45AC74CCEA842F}, // -106
|
||||
{0x92C8AE6B464FC96F, 0x3B0B8BC90012929E}, // -105
|
||||
{0xB77ADA0617E3BBCB, 0x09CE6EBB40173745}, // -104
|
||||
{0xE55990879DDCAABD, 0xCC420A6A101D0516}, // -103
|
||||
{0x8F57FA54C2A9EAB6, 0x9FA946824A12232E}, // -102
|
||||
{0xB32DF8E9F3546564, 0x47939822DC96ABFA}, // -101
|
||||
{0xDFF9772470297EBD, 0x59787E2B93BC56F8}, // -100
|
||||
{0x8BFBEA76C619EF36, 0x57EB4EDB3C55B65B}, // -99
|
||||
{0xAEFAE51477A06B03, 0xEDE622920B6B23F2}, // -98
|
||||
{0xDAB99E59958885C4, 0xE95FAB368E45ECEE}, // -97
|
||||
{0x88B402F7FD75539B, 0x11DBCB0218EBB415}, // -96
|
||||
{0xAAE103B5FCD2A881, 0xD652BDC29F26A11A}, // -95
|
||||
{0xD59944A37C0752A2, 0x4BE76D3346F04960}, // -94
|
||||
{0x857FCAE62D8493A5, 0x6F70A4400C562DDC}, // -93
|
||||
{0xA6DFBD9FB8E5B88E, 0xCB4CCD500F6BB953}, // -92
|
||||
{0xD097AD07A71F26B2, 0x7E2000A41346A7A8}, // -91
|
||||
{0x825ECC24C873782F, 0x8ED400668C0C28C9}, // -90
|
||||
{0xA2F67F2DFA90563B, 0x728900802F0F32FB}, // -89
|
||||
{0xCBB41EF979346BCA, 0x4F2B40A03AD2FFBA}, // -88
|
||||
{0xFEA126B7D78186BC, 0xE2F610C84987BFA9}, // -87
|
||||
{0x9F24B832E6B0F436, 0x0DD9CA7D2DF4D7CA}, // -86
|
||||
{0xC6EDE63FA05D3143, 0x91503D1C79720DBC}, // -85
|
||||
{0xF8A95FCF88747D94, 0x75A44C6397CE912B}, // -84
|
||||
{0x9B69DBE1B548CE7C, 0xC986AFBE3EE11ABB}, // -83
|
||||
{0xC24452DA229B021B, 0xFBE85BADCE996169}, // -82
|
||||
{0xF2D56790AB41C2A2, 0xFAE27299423FB9C4}, // -81
|
||||
{0x97C560BA6B0919A5, 0xDCCD879FC967D41B}, // -80
|
||||
{0xBDB6B8E905CB600F, 0x5400E987BBC1C921}, // -79
|
||||
{0xED246723473E3813, 0x290123E9AAB23B69}, // -78
|
||||
{0x9436C0760C86E30B, 0xF9A0B6720AAF6522}, // -77
|
||||
{0xB94470938FA89BCE, 0xF808E40E8D5B3E6A}, // -76
|
||||
{0xE7958CB87392C2C2, 0xB60B1D1230B20E05}, // -75
|
||||
{0x90BD77F3483BB9B9, 0xB1C6F22B5E6F48C3}, // -74
|
||||
{0xB4ECD5F01A4AA828, 0x1E38AEB6360B1AF4}, // -73
|
||||
{0xE2280B6C20DD5232, 0x25C6DA63C38DE1B1}, // -72
|
||||
{0x8D590723948A535F, 0x579C487E5A38AD0F}, // -71
|
||||
{0xB0AF48EC79ACE837, 0x2D835A9DF0C6D852}, // -70
|
||||
{0xDCDB1B2798182244, 0xF8E431456CF88E66}, // -69
|
||||
{0x8A08F0F8BF0F156B, 0x1B8E9ECB641B5900}, // -68
|
||||
{0xAC8B2D36EED2DAC5, 0xE272467E3D222F40}, // -67
|
||||
{0xD7ADF884AA879177, 0x5B0ED81DCC6ABB10}, // -66
|
||||
{0x86CCBB52EA94BAEA, 0x98E947129FC2B4EA}, // -65
|
||||
{0xA87FEA27A539E9A5, 0x3F2398D747B36225}, // -64
|
||||
{0xD29FE4B18E88640E, 0x8EEC7F0D19A03AAE}, // -63
|
||||
{0x83A3EEEEF9153E89, 0x1953CF68300424AD}, // -62
|
||||
{0xA48CEAAAB75A8E2B, 0x5FA8C3423C052DD8}, // -61
|
||||
{0xCDB02555653131B6, 0x3792F412CB06794E}, // -60
|
||||
{0x808E17555F3EBF11, 0xE2BBD88BBEE40BD1}, // -59
|
||||
{0xA0B19D2AB70E6ED6, 0x5B6ACEAEAE9D0EC5}, // -58
|
||||
{0xC8DE047564D20A8B, 0xF245825A5A445276}, // -57
|
||||
{0xFB158592BE068D2E, 0xEED6E2F0F0D56713}, // -56
|
||||
{0x9CED737BB6C4183D, 0x55464DD69685606C}, // -55
|
||||
{0xC428D05AA4751E4C, 0xAA97E14C3C26B887}, // -54
|
||||
{0xF53304714D9265DF, 0xD53DD99F4B3066A9}, // -53
|
||||
{0x993FE2C6D07B7FAB, 0xE546A8038EFE402A}, // -52
|
||||
{0xBF8FDB78849A5F96, 0xDE98520472BDD034}, // -51
|
||||
{0xEF73D256A5C0F77C, 0x963E66858F6D4441}, // -50
|
||||
{0x95A8637627989AAD, 0xDDE7001379A44AA9}, // -49
|
||||
{0xBB127C53B17EC159, 0x5560C018580D5D53}, // -48
|
||||
{0xE9D71B689DDE71AF, 0xAAB8F01E6E10B4A7}, // -47
|
||||
{0x9226712162AB070D, 0xCAB3961304CA70E9}, // -46
|
||||
{0xB6B00D69BB55C8D1, 0x3D607B97C5FD0D23}, // -45
|
||||
{0xE45C10C42A2B3B05, 0x8CB89A7DB77C506B}, // -44
|
||||
{0x8EB98A7A9A5B04E3, 0x77F3608E92ADB243}, // -43
|
||||
{0xB267ED1940F1C61C, 0x55F038B237591ED4}, // -42
|
||||
{0xDF01E85F912E37A3, 0x6B6C46DEC52F6689}, // -41
|
||||
{0x8B61313BBABCE2C6, 0x2323AC4B3B3DA016}, // -40
|
||||
{0xAE397D8AA96C1B77, 0xABEC975E0A0D081B}, // -39
|
||||
{0xD9C7DCED53C72255, 0x96E7BD358C904A22}, // -38
|
||||
{0x881CEA14545C7575, 0x7E50D64177DA2E55}, // -37
|
||||
{0xAA242499697392D2, 0xDDE50BD1D5D0B9EA}, // -36
|
||||
{0xD4AD2DBFC3D07787, 0x955E4EC64B44E865}, // -35
|
||||
{0x84EC3C97DA624AB4, 0xBD5AF13BEF0B113F}, // -34
|
||||
{0xA6274BBDD0FADD61, 0xECB1AD8AEACDD58F}, // -33
|
||||
{0xCFB11EAD453994BA, 0x67DE18EDA5814AF3}, // -32
|
||||
{0x81CEB32C4B43FCF4, 0x80EACF948770CED8}, // -31
|
||||
{0xA2425FF75E14FC31, 0xA1258379A94D028E}, // -30
|
||||
{0xCAD2F7F5359A3B3E, 0x096EE45813A04331}, // -29
|
||||
{0xFD87B5F28300CA0D, 0x8BCA9D6E188853FD}, // -28
|
||||
{0x9E74D1B791E07E48, 0x775EA264CF55347E}, // -27
|
||||
{0xC612062576589DDA, 0x95364AFE032A819E}, // -26
|
||||
{0xF79687AED3EEC551, 0x3A83DDBD83F52205}, // -25
|
||||
{0x9ABE14CD44753B52, 0xC4926A9672793543}, // -24
|
||||
{0xC16D9A0095928A27, 0x75B7053C0F178294}, // -23
|
||||
{0xF1C90080BAF72CB1, 0x5324C68B12DD6339}, // -22
|
||||
{0x971DA05074DA7BEE, 0xD3F6FC16EBCA5E04}, // -21
|
||||
{0xBCE5086492111AEA, 0x88F4BB1CA6BCF585}, // -20
|
||||
{0xEC1E4A7DB69561A5, 0x2B31E9E3D06C32E6}, // -19
|
||||
{0x9392EE8E921D5D07, 0x3AFF322E62439FD0}, // -18
|
||||
{0xB877AA3236A4B449, 0x09BEFEB9FAD487C3}, // -17
|
||||
{0xE69594BEC44DE15B, 0x4C2EBE687989A9B4}, // -16
|
||||
{0x901D7CF73AB0ACD9, 0x0F9D37014BF60A11}, // -15
|
||||
{0xB424DC35095CD80F, 0x538484C19EF38C95}, // -14
|
||||
{0xE12E13424BB40E13, 0x2865A5F206B06FBA}, // -13
|
||||
{0x8CBCCC096F5088CB, 0xF93F87B7442E45D4}, // -12
|
||||
{0xAFEBFF0BCB24AAFE, 0xF78F69A51539D749}, // -11
|
||||
{0xDBE6FECEBDEDD5BE, 0xB573440E5A884D1C}, // -10
|
||||
{0x89705F4136B4A597, 0x31680A88F8953031}, // -9
|
||||
{0xABCC77118461CEFC, 0xFDC20D2B36BA7C3E}, // -8
|
||||
{0xD6BF94D5E57A42BC, 0x3D32907604691B4D}, // -7
|
||||
{0x8637BD05AF6C69B5, 0xA63F9A49C2C1B110}, // -6
|
||||
{0xA7C5AC471B478423, 0x0FCF80DC33721D54}, // -5
|
||||
{0xD1B71758E219652B, 0xD3C36113404EA4A9}, // -4
|
||||
{0x83126E978D4FDF3B, 0x645A1CAC083126EA}, // -3
|
||||
{0xA3D70A3D70A3D70A, 0x3D70A3D70A3D70A4}, // -2
|
||||
{0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCD}, // -1
|
||||
{0x8000000000000000, 0x0000000000000000}, // 0
|
||||
{0xA000000000000000, 0x0000000000000000}, // 1
|
||||
{0xC800000000000000, 0x0000000000000000}, // 2
|
||||
{0xFA00000000000000, 0x0000000000000000}, // 3
|
||||
{0x9C40000000000000, 0x0000000000000000}, // 4
|
||||
{0xC350000000000000, 0x0000000000000000}, // 5
|
||||
{0xF424000000000000, 0x0000000000000000}, // 6
|
||||
{0x9896800000000000, 0x0000000000000000}, // 7
|
||||
{0xBEBC200000000000, 0x0000000000000000}, // 8
|
||||
{0xEE6B280000000000, 0x0000000000000000}, // 9
|
||||
{0x9502F90000000000, 0x0000000000000000}, // 10
|
||||
{0xBA43B74000000000, 0x0000000000000000}, // 11
|
||||
{0xE8D4A51000000000, 0x0000000000000000}, // 12
|
||||
{0x9184E72A00000000, 0x0000000000000000}, // 13
|
||||
{0xB5E620F480000000, 0x0000000000000000}, // 14
|
||||
{0xE35FA931A0000000, 0x0000000000000000}, // 15
|
||||
{0x8E1BC9BF04000000, 0x0000000000000000}, // 16
|
||||
{0xB1A2BC2EC5000000, 0x0000000000000000}, // 17
|
||||
{0xDE0B6B3A76400000, 0x0000000000000000}, // 18
|
||||
{0x8AC7230489E80000, 0x0000000000000000}, // 19
|
||||
{0xAD78EBC5AC620000, 0x0000000000000000}, // 20
|
||||
{0xD8D726B7177A8000, 0x0000000000000000}, // 21
|
||||
{0x878678326EAC9000, 0x0000000000000000}, // 22
|
||||
{0xA968163F0A57B400, 0x0000000000000000}, // 23
|
||||
{0xD3C21BCECCEDA100, 0x0000000000000000}, // 24
|
||||
{0x84595161401484A0, 0x0000000000000000}, // 25
|
||||
{0xA56FA5B99019A5C8, 0x0000000000000000}, // 26
|
||||
{0xCECB8F27F4200F3A, 0x0000000000000000}, // 27
|
||||
{0x813F3978F8940984, 0x4000000000000000}, // 28
|
||||
{0xA18F07D736B90BE5, 0x5000000000000000}, // 29
|
||||
{0xC9F2C9CD04674EDE, 0xA400000000000000}, // 30
|
||||
{0xFC6F7C4045812296, 0x4D00000000000000}, // 31
|
||||
{0x9DC5ADA82B70B59D, 0xF020000000000000}, // 32
|
||||
{0xC5371912364CE305, 0x6C28000000000000}, // 33
|
||||
{0xF684DF56C3E01BC6, 0xC732000000000000}, // 34
|
||||
{0x9A130B963A6C115C, 0x3C7F400000000000}, // 35
|
||||
{0xC097CE7BC90715B3, 0x4B9F100000000000}, // 36
|
||||
{0xF0BDC21ABB48DB20, 0x1E86D40000000000}, // 37
|
||||
{0x96769950B50D88F4, 0x1314448000000000}, // 38
|
||||
{0xBC143FA4E250EB31, 0x17D955A000000000}, // 39
|
||||
{0xEB194F8E1AE525FD, 0x5DCFAB0800000000}, // 40
|
||||
{0x92EFD1B8D0CF37BE, 0x5AA1CAE500000000}, // 41
|
||||
{0xB7ABC627050305AD, 0xF14A3D9E40000000}, // 42
|
||||
{0xE596B7B0C643C719, 0x6D9CCD05D0000000}, // 43
|
||||
{0x8F7E32CE7BEA5C6F, 0xE4820023A2000000}, // 44
|
||||
{0xB35DBF821AE4F38B, 0xDDA2802C8A800000}, // 45
|
||||
{0xE0352F62A19E306E, 0xD50B2037AD200000}, // 46
|
||||
{0x8C213D9DA502DE45, 0x4526F422CC340000}, // 47
|
||||
{0xAF298D050E4395D6, 0x9670B12B7F410000}, // 48
|
||||
{0xDAF3F04651D47B4C, 0x3C0CDD765F114000}, // 49
|
||||
{0x88D8762BF324CD0F, 0xA5880A69FB6AC800}, // 50
|
||||
{0xAB0E93B6EFEE0053, 0x8EEA0D047A457A00}, // 51
|
||||
{0xD5D238A4ABE98068, 0x72A4904598D6D880}, // 52
|
||||
{0x85A36366EB71F041, 0x47A6DA2B7F864750}, // 53
|
||||
{0xA70C3C40A64E6C51, 0x999090B65F67D924}, // 54
|
||||
{0xD0CF4B50CFE20765, 0xFFF4B4E3F741CF6D}, // 55
|
||||
{0x82818F1281ED449F, 0xBFF8F10E7A8921A5}, // 56
|
||||
{0xA321F2D7226895C7, 0xAFF72D52192B6A0E}, // 57
|
||||
{0xCBEA6F8CEB02BB39, 0x9BF4F8A69F764491}, // 58
|
||||
{0xFEE50B7025C36A08, 0x02F236D04753D5B5}, // 59
|
||||
{0x9F4F2726179A2245, 0x01D762422C946591}, // 60
|
||||
{0xC722F0EF9D80AAD6, 0x424D3AD2B7B97EF6}, // 61
|
||||
{0xF8EBAD2B84E0D58B, 0xD2E0898765A7DEB3}, // 62
|
||||
{0x9B934C3B330C8577, 0x63CC55F49F88EB30}, // 63
|
||||
{0xC2781F49FFCFA6D5, 0x3CBF6B71C76B25FC}, // 64
|
||||
{0xF316271C7FC3908A, 0x8BEF464E3945EF7B}, // 65
|
||||
{0x97EDD871CFDA3A56, 0x97758BF0E3CBB5AD}, // 66
|
||||
{0xBDE94E8E43D0C8EC, 0x3D52EEED1CBEA318}, // 67
|
||||
{0xED63A231D4C4FB27, 0x4CA7AAA863EE4BDE}, // 68
|
||||
{0x945E455F24FB1CF8, 0x8FE8CAA93E74EF6B}, // 69
|
||||
{0xB975D6B6EE39E436, 0xB3E2FD538E122B45}, // 70
|
||||
{0xE7D34C64A9C85D44, 0x60DBBCA87196B617}, // 71
|
||||
{0x90E40FBEEA1D3A4A, 0xBC8955E946FE31CE}, // 72
|
||||
{0xB51D13AEA4A488DD, 0x6BABAB6398BDBE42}, // 73
|
||||
{0xE264589A4DCDAB14, 0xC696963C7EED2DD2}, // 74
|
||||
{0x8D7EB76070A08AEC, 0xFC1E1DE5CF543CA3}, // 75
|
||||
{0xB0DE65388CC8ADA8, 0x3B25A55F43294BCC}, // 76
|
||||
{0xDD15FE86AFFAD912, 0x49EF0EB713F39EBF}, // 77
|
||||
{0x8A2DBF142DFCC7AB, 0x6E3569326C784338}, // 78
|
||||
{0xACB92ED9397BF996, 0x49C2C37F07965405}, // 79
|
||||
{0xD7E77A8F87DAF7FB, 0xDC33745EC97BE907}, // 80
|
||||
{0x86F0AC99B4E8DAFD, 0x69A028BB3DED71A4}, // 81
|
||||
{0xA8ACD7C0222311BC, 0xC40832EA0D68CE0D}, // 82
|
||||
{0xD2D80DB02AABD62B, 0xF50A3FA490C30191}, // 83
|
||||
{0x83C7088E1AAB65DB, 0x792667C6DA79E0FB}, // 84
|
||||
{0xA4B8CAB1A1563F52, 0x577001B891185939}, // 85
|
||||
{0xCDE6FD5E09ABCF26, 0xED4C0226B55E6F87}, // 86
|
||||
{0x80B05E5AC60B6178, 0x544F8158315B05B5}, // 87
|
||||
{0xA0DC75F1778E39D6, 0x696361AE3DB1C722}, // 88
|
||||
{0xC913936DD571C84C, 0x03BC3A19CD1E38EA}, // 89
|
||||
{0xFB5878494ACE3A5F, 0x04AB48A04065C724}, // 90
|
||||
{0x9D174B2DCEC0E47B, 0x62EB0D64283F9C77}, // 91
|
||||
{0xC45D1DF942711D9A, 0x3BA5D0BD324F8395}, // 92
|
||||
{0xF5746577930D6500, 0xCA8F44EC7EE3647A}, // 93
|
||||
{0x9968BF6ABBE85F20, 0x7E998B13CF4E1ECC}, // 94
|
||||
{0xBFC2EF456AE276E8, 0x9E3FEDD8C321A67F}, // 95
|
||||
{0xEFB3AB16C59B14A2, 0xC5CFE94EF3EA101F}, // 96
|
||||
{0x95D04AEE3B80ECE5, 0xBBA1F1D158724A13}, // 97
|
||||
{0xBB445DA9CA61281F, 0x2A8A6E45AE8EDC98}, // 98
|
||||
{0xEA1575143CF97226, 0xF52D09D71A3293BE}, // 99
|
||||
{0x924D692CA61BE758, 0x593C2626705F9C57}, // 100
|
||||
{0xB6E0C377CFA2E12E, 0x6F8B2FB00C77836D}, // 101
|
||||
{0xE498F455C38B997A, 0x0B6DFB9C0F956448}, // 102
|
||||
{0x8EDF98B59A373FEC, 0x4724BD4189BD5EAD}, // 103
|
||||
{0xB2977EE300C50FE7, 0x58EDEC91EC2CB658}, // 104
|
||||
{0xDF3D5E9BC0F653E1, 0x2F2967B66737E3EE}, // 105
|
||||
{0x8B865B215899F46C, 0xBD79E0D20082EE75}, // 106
|
||||
{0xAE67F1E9AEC07187, 0xECD8590680A3AA12}, // 107
|
||||
{0xDA01EE641A708DE9, 0xE80E6F4820CC9496}, // 108
|
||||
{0x884134FE908658B2, 0x3109058D147FDCDE}, // 109
|
||||
{0xAA51823E34A7EEDE, 0xBD4B46F0599FD416}, // 110
|
||||
{0xD4E5E2CDC1D1EA96, 0x6C9E18AC7007C91B}, // 111
|
||||
{0x850FADC09923329E, 0x03E2CF6BC604DDB1}, // 112
|
||||
{0xA6539930BF6BFF45, 0x84DB8346B786151D}, // 113
|
||||
{0xCFE87F7CEF46FF16, 0xE612641865679A64}, // 114
|
||||
{0x81F14FAE158C5F6E, 0x4FCB7E8F3F60C07F}, // 115
|
||||
{0xA26DA3999AEF7749, 0xE3BE5E330F38F09E}, // 116
|
||||
{0xCB090C8001AB551C, 0x5CADF5BFD3072CC6}, // 117
|
||||
{0xFDCB4FA002162A63, 0x73D9732FC7C8F7F7}, // 118
|
||||
{0x9E9F11C4014DDA7E, 0x2867E7FDDCDD9AFB}, // 119
|
||||
{0xC646D63501A1511D, 0xB281E1FD541501B9}, // 120
|
||||
{0xF7D88BC24209A565, 0x1F225A7CA91A4227}, // 121
|
||||
{0x9AE757596946075F, 0x3375788DE9B06959}, // 122
|
||||
{0xC1A12D2FC3978937, 0x0052D6B1641C83AF}, // 123
|
||||
{0xF209787BB47D6B84, 0xC0678C5DBD23A49B}, // 124
|
||||
{0x9745EB4D50CE6332, 0xF840B7BA963646E1}, // 125
|
||||
{0xBD176620A501FBFF, 0xB650E5A93BC3D899}, // 126
|
||||
{0xEC5D3FA8CE427AFF, 0xA3E51F138AB4CEBF}, // 127
|
||||
{0x93BA47C980E98CDF, 0xC66F336C36B10138}, // 128
|
||||
{0xB8A8D9BBE123F017, 0xB80B0047445D4185}, // 129
|
||||
{0xE6D3102AD96CEC1D, 0xA60DC059157491E6}, // 130
|
||||
{0x9043EA1AC7E41392, 0x87C89837AD68DB30}, // 131
|
||||
{0xB454E4A179DD1877, 0x29BABE4598C311FC}, // 132
|
||||
{0xE16A1DC9D8545E94, 0xF4296DD6FEF3D67B}, // 133
|
||||
{0x8CE2529E2734BB1D, 0x1899E4A65F58660D}, // 134
|
||||
{0xB01AE745B101E9E4, 0x5EC05DCFF72E7F90}, // 135
|
||||
{0xDC21A1171D42645D, 0x76707543F4FA1F74}, // 136
|
||||
{0x899504AE72497EBA, 0x6A06494A791C53A9}, // 137
|
||||
{0xABFA45DA0EDBDE69, 0x0487DB9D17636893}, // 138
|
||||
{0xD6F8D7509292D603, 0x45A9D2845D3C42B7}, // 139
|
||||
{0x865B86925B9BC5C2, 0x0B8A2392BA45A9B3}, // 140
|
||||
{0xA7F26836F282B732, 0x8E6CAC7768D7141F}, // 141
|
||||
{0xD1EF0244AF2364FF, 0x3207D795430CD927}, // 142
|
||||
{0x8335616AED761F1F, 0x7F44E6BD49E807B9}, // 143
|
||||
{0xA402B9C5A8D3A6E7, 0x5F16206C9C6209A7}, // 144
|
||||
{0xCD036837130890A1, 0x36DBA887C37A8C10}, // 145
|
||||
{0x802221226BE55A64, 0xC2494954DA2C978A}, // 146
|
||||
{0xA02AA96B06DEB0FD, 0xF2DB9BAA10B7BD6D}, // 147
|
||||
{0xC83553C5C8965D3D, 0x6F92829494E5ACC8}, // 148
|
||||
{0xFA42A8B73ABBF48C, 0xCB772339BA1F17FA}, // 149
|
||||
{0x9C69A97284B578D7, 0xFF2A760414536EFC}, // 150
|
||||
{0xC38413CF25E2D70D, 0xFEF5138519684ABB}, // 151
|
||||
{0xF46518C2EF5B8CD1, 0x7EB258665FC25D6A}, // 152
|
||||
{0x98BF2F79D5993802, 0xEF2F773FFBD97A62}, // 153
|
||||
{0xBEEEFB584AFF8603, 0xAAFB550FFACFD8FB}, // 154
|
||||
{0xEEAABA2E5DBF6784, 0x95BA2A53F983CF39}, // 155
|
||||
{0x952AB45CFA97A0B2, 0xDD945A747BF26184}, // 156
|
||||
{0xBA756174393D88DF, 0x94F971119AEEF9E5}, // 157
|
||||
{0xE912B9D1478CEB17, 0x7A37CD5601AAB85E}, // 158
|
||||
{0x91ABB422CCB812EE, 0xAC62E055C10AB33B}, // 159
|
||||
{0xB616A12B7FE617AA, 0x577B986B314D600A}, // 160
|
||||
{0xE39C49765FDF9D94, 0xED5A7E85FDA0B80C}, // 161
|
||||
{0x8E41ADE9FBEBC27D, 0x14588F13BE847308}, // 162
|
||||
{0xB1D219647AE6B31C, 0x596EB2D8AE258FC9}, // 163
|
||||
{0xDE469FBD99A05FE3, 0x6FCA5F8ED9AEF3BC}, // 164
|
||||
{0x8AEC23D680043BEE, 0x25DE7BB9480D5855}, // 165
|
||||
{0xADA72CCC20054AE9, 0xAF561AA79A10AE6B}, // 166
|
||||
{0xD910F7FF28069DA4, 0x1B2BA1518094DA05}, // 167
|
||||
{0x87AA9AFF79042286, 0x90FB44D2F05D0843}, // 168
|
||||
{0xA99541BF57452B28, 0x353A1607AC744A54}, // 169
|
||||
{0xD3FA922F2D1675F2, 0x42889B8997915CE9}, // 170
|
||||
{0x847C9B5D7C2E09B7, 0x69956135FEBADA12}, // 171
|
||||
{0xA59BC234DB398C25, 0x43FAB9837E699096}, // 172
|
||||
{0xCF02B2C21207EF2E, 0x94F967E45E03F4BC}, // 173
|
||||
{0x8161AFB94B44F57D, 0x1D1BE0EEBAC278F6}, // 174
|
||||
{0xA1BA1BA79E1632DC, 0x6462D92A69731733}, // 175
|
||||
{0xCA28A291859BBF93, 0x7D7B8F7503CFDCFF}, // 176
|
||||
{0xFCB2CB35E702AF78, 0x5CDA735244C3D43F}, // 177
|
||||
{0x9DEFBF01B061ADAB, 0x3A0888136AFA64A8}, // 178
|
||||
{0xC56BAEC21C7A1916, 0x088AAA1845B8FDD1}, // 179
|
||||
{0xF6C69A72A3989F5B, 0x8AAD549E57273D46}, // 180
|
||||
{0x9A3C2087A63F6399, 0x36AC54E2F678864C}, // 181
|
||||
{0xC0CB28A98FCF3C7F, 0x84576A1BB416A7DE}, // 182
|
||||
{0xF0FDF2D3F3C30B9F, 0x656D44A2A11C51D6}, // 183
|
||||
{0x969EB7C47859E743, 0x9F644AE5A4B1B326}, // 184
|
||||
{0xBC4665B596706114, 0x873D5D9F0DDE1FEF}, // 185
|
||||
{0xEB57FF22FC0C7959, 0xA90CB506D155A7EB}, // 186
|
||||
{0x9316FF75DD87CBD8, 0x09A7F12442D588F3}, // 187
|
||||
{0xB7DCBF5354E9BECE, 0x0C11ED6D538AEB30}, // 188
|
||||
{0xE5D3EF282A242E81, 0x8F1668C8A86DA5FB}, // 189
|
||||
{0x8FA475791A569D10, 0xF96E017D694487BD}, // 190
|
||||
{0xB38D92D760EC4455, 0x37C981DCC395A9AD}, // 191
|
||||
{0xE070F78D3927556A, 0x85BBE253F47B1418}, // 192
|
||||
{0x8C469AB843B89562, 0x93956D7478CCEC8F}, // 193
|
||||
{0xAF58416654A6BABB, 0x387AC8D1970027B3}, // 194
|
||||
{0xDB2E51BFE9D0696A, 0x06997B05FCC0319F}, // 195
|
||||
{0x88FCF317F22241E2, 0x441FECE3BDF81F04}, // 196
|
||||
{0xAB3C2FDDEEAAD25A, 0xD527E81CAD7626C4}, // 197
|
||||
{0xD60B3BD56A5586F1, 0x8A71E223D8D3B075}, // 198
|
||||
{0x85C7056562757456, 0xF6872D5667844E4A}, // 199
|
||||
{0xA738C6BEBB12D16C, 0xB428F8AC016561DC}, // 200
|
||||
{0xD106F86E69D785C7, 0xE13336D701BEBA53}, // 201
|
||||
{0x82A45B450226B39C, 0xECC0024661173474}, // 202
|
||||
{0xA34D721642B06084, 0x27F002D7F95D0191}, // 203
|
||||
{0xCC20CE9BD35C78A5, 0x31EC038DF7B441F5}, // 204
|
||||
{0xFF290242C83396CE, 0x7E67047175A15272}, // 205
|
||||
{0x9F79A169BD203E41, 0x0F0062C6E984D387}, // 206
|
||||
{0xC75809C42C684DD1, 0x52C07B78A3E60869}, // 207
|
||||
{0xF92E0C3537826145, 0xA7709A56CCDF8A83}, // 208
|
||||
{0x9BBCC7A142B17CCB, 0x88A66076400BB692}, // 209
|
||||
{0xC2ABF989935DDBFE, 0x6ACFF893D00EA436}, // 210
|
||||
{0xF356F7EBF83552FE, 0x0583F6B8C4124D44}, // 211
|
||||
{0x98165AF37B2153DE, 0xC3727A337A8B704B}, // 212
|
||||
{0xBE1BF1B059E9A8D6, 0x744F18C0592E4C5D}, // 213
|
||||
{0xEDA2EE1C7064130C, 0x1162DEF06F79DF74}, // 214
|
||||
{0x9485D4D1C63E8BE7, 0x8ADDCB5645AC2BA9}, // 215
|
||||
{0xB9A74A0637CE2EE1, 0x6D953E2BD7173693}, // 216
|
||||
{0xE8111C87C5C1BA99, 0xC8FA8DB6CCDD0438}, // 217
|
||||
{0x910AB1D4DB9914A0, 0x1D9C9892400A22A3}, // 218
|
||||
{0xB54D5E4A127F59C8, 0x2503BEB6D00CAB4C}, // 219
|
||||
{0xE2A0B5DC971F303A, 0x2E44AE64840FD61E}, // 220
|
||||
{0x8DA471A9DE737E24, 0x5CEAECFED289E5D3}, // 221
|
||||
{0xB10D8E1456105DAD, 0x7425A83E872C5F48}, // 222
|
||||
{0xDD50F1996B947518, 0xD12F124E28F7771A}, // 223
|
||||
{0x8A5296FFE33CC92F, 0x82BD6B70D99AAA70}, // 224
|
||||
{0xACE73CBFDC0BFB7B, 0x636CC64D1001550C}, // 225
|
||||
{0xD8210BEFD30EFA5A, 0x3C47F7E05401AA4F}, // 226
|
||||
{0x8714A775E3E95C78, 0x65ACFAEC34810A72}, // 227
|
||||
{0xA8D9D1535CE3B396, 0x7F1839A741A14D0E}, // 228
|
||||
{0xD31045A8341CA07C, 0x1EDE48111209A051}, // 229
|
||||
{0x83EA2B892091E44D, 0x934AED0AAB460433}, // 230
|
||||
{0xA4E4B66B68B65D60, 0xF81DA84D56178540}, // 231
|
||||
{0xCE1DE40642E3F4B9, 0x36251260AB9D668F}, // 232
|
||||
{0x80D2AE83E9CE78F3, 0xC1D72B7C6B42601A}, // 233
|
||||
{0xA1075A24E4421730, 0xB24CF65B8612F820}, // 234
|
||||
{0xC94930AE1D529CFC, 0xDEE033F26797B628}, // 235
|
||||
{0xFB9B7CD9A4A7443C, 0x169840EF017DA3B2}, // 236
|
||||
{0x9D412E0806E88AA5, 0x8E1F289560EE864F}, // 237
|
||||
{0xC491798A08A2AD4E, 0xF1A6F2BAB92A27E3}, // 238
|
||||
{0xF5B5D7EC8ACB58A2, 0xAE10AF696774B1DC}, // 239
|
||||
{0x9991A6F3D6BF1765, 0xACCA6DA1E0A8EF2A}, // 240
|
||||
{0xBFF610B0CC6EDD3F, 0x17FD090A58D32AF4}, // 241
|
||||
{0xEFF394DCFF8A948E, 0xDDFC4B4CEF07F5B1}, // 242
|
||||
{0x95F83D0A1FB69CD9, 0x4ABDAF101564F98F}, // 243
|
||||
{0xBB764C4CA7A4440F, 0x9D6D1AD41ABE37F2}, // 244
|
||||
{0xEA53DF5FD18D5513, 0x84C86189216DC5EE}, // 245
|
||||
{0x92746B9BE2F8552C, 0x32FD3CF5B4E49BB5}, // 246
|
||||
{0xB7118682DBB66A77, 0x3FBC8C33221DC2A2}, // 247
|
||||
{0xE4D5E82392A40515, 0x0FABAF3FEAA5334B}, // 248
|
||||
{0x8F05B1163BA6832D, 0x29CB4D87F2A7400F}, // 249
|
||||
{0xB2C71D5BCA9023F8, 0x743E20E9EF511013}, // 250
|
||||
{0xDF78E4B2BD342CF6, 0x914DA9246B255417}, // 251
|
||||
{0x8BAB8EEFB6409C1A, 0x1AD089B6C2F7548F}, // 252
|
||||
{0xAE9672ABA3D0C320, 0xA184AC2473B529B2}, // 253
|
||||
{0xDA3C0F568CC4F3E8, 0xC9E5D72D90A2741F}, // 254
|
||||
{0x8865899617FB1871, 0x7E2FA67C7A658893}, // 255
|
||||
{0xAA7EEBFB9DF9DE8D, 0xDDBB901B98FEEAB8}, // 256
|
||||
{0xD51EA6FA85785631, 0x552A74227F3EA566}, // 257
|
||||
{0x8533285C936B35DE, 0xD53A88958F872760}, // 258
|
||||
{0xA67FF273B8460356, 0x8A892ABAF368F138}, // 259
|
||||
{0xD01FEF10A657842C, 0x2D2B7569B0432D86}, // 260
|
||||
{0x8213F56A67F6B29B, 0x9C3B29620E29FC74}, // 261
|
||||
{0xA298F2C501F45F42, 0x8349F3BA91B47B90}, // 262
|
||||
{0xCB3F2F7642717713, 0x241C70A936219A74}, // 263
|
||||
{0xFE0EFB53D30DD4D7, 0xED238CD383AA0111}, // 264
|
||||
{0x9EC95D1463E8A506, 0xF4363804324A40AB}, // 265
|
||||
{0xC67BB4597CE2CE48, 0xB143C6053EDCD0D6}, // 266
|
||||
{0xF81AA16FDC1B81DA, 0xDD94B7868E94050B}, // 267
|
||||
{0x9B10A4E5E9913128, 0xCA7CF2B4191C8327}, // 268
|
||||
{0xC1D4CE1F63F57D72, 0xFD1C2F611F63A3F1}, // 269
|
||||
{0xF24A01A73CF2DCCF, 0xBC633B39673C8CED}, // 270
|
||||
{0x976E41088617CA01, 0xD5BE0503E085D814}, // 271
|
||||
{0xBD49D14AA79DBC82, 0x4B2D8644D8A74E19}, // 272
|
||||
{0xEC9C459D51852BA2, 0xDDF8E7D60ED1219F}, // 273
|
||||
{0x93E1AB8252F33B45, 0xCABB90E5C942B504}, // 274
|
||||
{0xB8DA1662E7B00A17, 0x3D6A751F3B936244}, // 275
|
||||
{0xE7109BFBA19C0C9D, 0x0CC512670A783AD5}, // 276
|
||||
{0x906A617D450187E2, 0x27FB2B80668B24C6}, // 277
|
||||
{0xB484F9DC9641E9DA, 0xB1F9F660802DEDF7}, // 278
|
||||
{0xE1A63853BBD26451, 0x5E7873F8A0396974}, // 279
|
||||
{0x8D07E33455637EB2, 0xDB0B487B6423E1E9}, // 280
|
||||
{0xB049DC016ABC5E5F, 0x91CE1A9A3D2CDA63}, // 281
|
||||
{0xDC5C5301C56B75F7, 0x7641A140CC7810FC}, // 282
|
||||
{0x89B9B3E11B6329BA, 0xA9E904C87FCB0A9E}, // 283
|
||||
{0xAC2820D9623BF429, 0x546345FA9FBDCD45}, // 284
|
||||
{0xD732290FBACAF133, 0xA97C177947AD4096}, // 285
|
||||
{0x867F59A9D4BED6C0, 0x49ED8EABCCCC485E}, // 286
|
||||
{0xA81F301449EE8C70, 0x5C68F256BFFF5A75}, // 287
|
||||
{0xD226FC195C6A2F8C, 0x73832EEC6FFF3112}, // 288
|
||||
{0x83585D8FD9C25DB7, 0xC831FD53C5FF7EAC}, // 289
|
||||
{0xA42E74F3D032F525, 0xBA3E7CA8B77F5E56}, // 290
|
||||
{0xCD3A1230C43FB26F, 0x28CE1BD2E55F35EC}, // 291
|
||||
{0x80444B5E7AA7CF85, 0x7980D163CF5B81B4}, // 292
|
||||
{0xA0555E361951C366, 0xD7E105BCC3326220}, // 293
|
||||
{0xC86AB5C39FA63440, 0x8DD9472BF3FEFAA8}, // 294
|
||||
{0xFA856334878FC150, 0xB14F98F6F0FEB952}, // 295
|
||||
{0x9C935E00D4B9D8D2, 0x6ED1BF9A569F33D4}, // 296
|
||||
{0xC3B8358109E84F07, 0x0A862F80EC4700C9}, // 297
|
||||
{0xF4A642E14C6262C8, 0xCD27BB612758C0FB}, // 298
|
||||
{0x98E7E9CCCFBD7DBD, 0x8038D51CB897789D}, // 299
|
||||
{0xBF21E44003ACDD2C, 0xE0470A63E6BD56C4}, // 300
|
||||
{0xEEEA5D5004981478, 0x1858CCFCE06CAC75}, // 301
|
||||
{0x95527A5202DF0CCB, 0x0F37801E0C43EBC9}, // 302
|
||||
{0xBAA718E68396CFFD, 0xD30560258F54E6BB}, // 303
|
||||
{0xE950DF20247C83FD, 0x47C6B82EF32A206A}, // 304
|
||||
{0x91D28B7416CDD27E, 0x4CDC331D57FA5442}, // 305
|
||||
{0xB6472E511C81471D, 0xE0133FE4ADF8E953}, // 306
|
||||
{0xE3D8F9E563A198E5, 0x58180FDDD97723A7}, // 307
|
||||
{0x8E679C2F5E44FF8F, 0x570F09EAA7EA7649}, // 308
|
||||
{0xB201833B35D63F73, 0x2CD2CC6551E513DB}, // 309
|
||||
{0xDE81E40A034BCF4F, 0xF8077F7EA65E58D2}, // 310
|
||||
{0x8B112E86420F6191, 0xFB04AFAF27FAF783}, // 311
|
||||
{0xADD57A27D29339F6, 0x79C5DB9AF1F9B564}, // 312
|
||||
{0xD94AD8B1C7380874, 0x18375281AE7822BD}, // 313
|
||||
{0x87CEC76F1C830548, 0x8F2293910D0B15B6}, // 314
|
||||
{0xA9C2794AE3A3C69A, 0xB2EB3875504DDB23}, // 315
|
||||
{0xD433179D9C8CB841, 0x5FA60692A46151EC}, // 316
|
||||
{0x849FEEC281D7F328, 0xDBC7C41BA6BCD334}, // 317
|
||||
{0xA5C7EA73224DEFF3, 0x12B9B522906C0801}, // 318
|
||||
{0xCF39E50FEAE16BEF, 0xD768226B34870A01}, // 319
|
||||
{0x81842F29F2CCE375, 0xE6A1158300D46641}, // 320
|
||||
{0xA1E53AF46F801C53, 0x60495AE3C1097FD1}, // 321
|
||||
{0xCA5E89B18B602368, 0x385BB19CB14BDFC5}, // 322
|
||||
{0xFCF62C1DEE382C42, 0x46729E03DD9ED7B6}, // 323
|
||||
{0x9E19DB92B4E31BA9, 0x6C07A2C26A8346D2}, // 324
|
||||
};
|
||||
return g[k - KMIN];
|
||||
#undef KMIN
|
||||
#undef KMAX
|
||||
}
|
||||
|
||||
#endif
|
||||
41
native/test/xassert.h
Normal file
41
native/test/xassert.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2022 ByteDance Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef XASSERT_H
|
||||
#define XASSERT_H
|
||||
|
||||
#ifndef DEBUG
|
||||
#define xassert(expr) ((void)0)
|
||||
#else
|
||||
#include "xprintf.h"
|
||||
#define xassert(expr) \
|
||||
((expr) \
|
||||
? ((void)0) \
|
||||
: _xassert(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__))
|
||||
|
||||
static void* raise = 0;
|
||||
static void xabort() {
|
||||
*(int*)(raise) = 1;
|
||||
}
|
||||
static void _xassert(const char *assertion, const char *file,
|
||||
const unsigned line, const char *func) {
|
||||
xprintf("%s:%u: %s Assertion `%s' failed.\n",
|
||||
file, line, func ? func : "?", assertion);
|
||||
xabort();
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
#endif // XASSERT_H
|
||||
|
|
@ -53,6 +53,28 @@ static void printstr(const char *s)
|
|||
static void printint(int64_t v)
|
||||
{
|
||||
char neg = 0;
|
||||
char buf[32] = {};
|
||||
char *p = &buf[31];
|
||||
uint64_t u;
|
||||
if (v < 0) {
|
||||
u = ~v + 1;
|
||||
neg = 1;
|
||||
} else {
|
||||
u = v;
|
||||
}
|
||||
while (u)
|
||||
{
|
||||
*--p = (u % 10) + '0';
|
||||
u /= 10;
|
||||
}
|
||||
if (neg) {
|
||||
*--p = '-';
|
||||
}
|
||||
printstr(p);
|
||||
}
|
||||
|
||||
static void printuint(uint64_t v)
|
||||
{
|
||||
char buf[32] = {};
|
||||
char *p = &buf[31];
|
||||
if (v == 0)
|
||||
|
|
@ -60,20 +82,11 @@ static void printint(int64_t v)
|
|||
printch('0');
|
||||
return;
|
||||
}
|
||||
if (v < 0)
|
||||
{
|
||||
v = -v;
|
||||
neg = 1;
|
||||
}
|
||||
while (v)
|
||||
{
|
||||
*--p = (v % 10) + '0';
|
||||
v /= 10;
|
||||
}
|
||||
if (neg)
|
||||
{
|
||||
*--p = '-';
|
||||
}
|
||||
printstr(p);
|
||||
}
|
||||
|
||||
|
|
@ -160,16 +173,26 @@ static void xprintf(const char *fmt, ...)
|
|||
printch('%');
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
case 'g':
|
||||
{
|
||||
printgostr(__builtin_va_arg(va, GoString *));
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
{
|
||||
printstr(__builtin_va_arg(va, const char *));
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
{
|
||||
printint(__builtin_va_arg(va, int64_t));
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
printuint(__builtin_va_arg(va, uint64_t));
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
printint(__builtin_va_arg(va, double));
|
||||
|
|
@ -177,7 +200,7 @@ static void xprintf(const char *fmt, ...)
|
|||
}
|
||||
case 'c':
|
||||
{
|
||||
printch(__builtin_va_arg(va, const char));
|
||||
printch((char)(__builtin_va_arg(va, int)));
|
||||
break;
|
||||
}
|
||||
case 'x':
|
||||
|
|
|
|||
|
|
@ -67,8 +67,6 @@ static inline ssize_t valid_utf8_4byte(uint32_t ubin) {
|
|||
bit pattern [11110... 10...... 10...... 10......] (F0 80 80 80)
|
||||
---------------------------------------------------
|
||||
*/
|
||||
const uint32_t b1_mask = 0x00000080UL;
|
||||
const uint32_t b1_patt = 0x00000000UL;
|
||||
const uint32_t b2_mask = 0x0000C0E0UL;
|
||||
const uint32_t b2_patt = 0x000080C0UL;
|
||||
const uint32_t b2_requ = 0x0000001EUL;
|
||||
|
|
@ -82,10 +80,6 @@ static inline ssize_t valid_utf8_4byte(uint32_t ubin) {
|
|||
const uint32_t b4_err0 = 0x00000004UL;
|
||||
const uint32_t b4_err1 = 0x00003003UL;
|
||||
|
||||
#define is_valid_seq_1(uni) ( \
|
||||
((uni & b1_mask) == b1_patt) \
|
||||
)
|
||||
|
||||
#define is_valid_seq_2(uni) ( \
|
||||
((uni & b2_mask) == b2_patt) && \
|
||||
((uni & b2_requ)) \
|
||||
|
|
|
|||
Loading…
Reference in a new issue