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) } } }) } }