118 lines
2.5 KiB
Go
118 lines
2.5 KiB
Go
package copyx_test
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"git.yuntuo.hk/k2safe/go-omni/copyx"
|
|
)
|
|
|
|
func BenchmarkScenarios(b *testing.B) {
|
|
type request struct {
|
|
Name string
|
|
Count int64
|
|
Active bool
|
|
}
|
|
type result struct {
|
|
Label string
|
|
Count int64
|
|
Active bool
|
|
}
|
|
source := request{"sample", 9007199254740993, true}
|
|
option := copyx.WithFieldNames[request, result](map[string]string{"Name": "Label"})
|
|
copier, err := copyx.New(option)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
for _, reuse := range []bool{false, true} {
|
|
b.Run(fmt.Sprintf("struct/reuse%t", reuse), func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
var target result
|
|
var err error
|
|
if reuse {
|
|
err = copier.Copy(&target, source)
|
|
} else {
|
|
err = copyx.Copy(&target, source, option)
|
|
}
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
deep, _ := copyx.New(copyx.WithDeepCopy())
|
|
b.Run("bytes64KiB", func(b *testing.B) {
|
|
src := make([]byte, 64<<10)
|
|
b.SetBytes(int64(len(src)))
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
var dst []byte
|
|
if err := deep.Copy(&dst, src); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
src := map[string][]int{}
|
|
for i := 0; i < 100; i++ {
|
|
src[fmt.Sprint(i)] = []int{1, 2, 3}
|
|
}
|
|
b.Run("map100", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
var dst map[string][]int
|
|
if err := deep.Copy(&dst, src); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
cycle := &detail{Values: []int{1, 2, 3}}
|
|
cycle.Next = cycle
|
|
b.Run("cycle", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
var dst *detail
|
|
if err := deep.Copy(&dst, cycle); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
b.Run("parallelCycle", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
var dst *detail
|
|
if err := deep.Copy(&dst, cycle); err != nil {
|
|
b.Error(err)
|
|
return
|
|
}
|
|
}
|
|
})
|
|
})
|
|
for _, fresh := range []bool{false, true} {
|
|
b.Run(fmt.Sprintf("converter/fresh%t", fresh), func(b *testing.B) {
|
|
c, err := copyx.New(copyx.WithDeepCopy(), copyx.WithConverter(func(v []int) ([]int, error) {
|
|
if fresh {
|
|
return append([]int(nil), v...), nil
|
|
}
|
|
return v, nil
|
|
}))
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
src := []int{1, 2, 3}
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
var dst []int
|
|
err := c.Copy(&dst, src)
|
|
if fresh && err != nil || !fresh && !errors.Is(err, copyx.ErrSharedReference) {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|