github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/reflector/performance_test.go (about)

     1  package reflector
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strconv"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func stopwatch(n int, title string) func() {
    12  	start := time.Now()
    13  	return func() {
    14  		fmt.Println(title)
    15  		fmt.Printf("%12s= %d\n", "n", n)
    16  		const dateFormat = "2006-01-02 15:04:05.123"
    17  		fmt.Printf("%12s: %s\n", "started", start.Format(dateFormat))
    18  		fmt.Printf("%12s: %fs\n", "duration", time.Since(start).Seconds())
    19  	}
    20  }
    21  
    22  func performanceN(envN string) int {
    23  	n, _ := strconv.ParseInt(envN, 10, 64)
    24  	const defaultN = 1000
    25  	if n < 1 {
    26  		n = defaultN
    27  	}
    28  	return int(n)
    29  }
    30  
    31  // Utility to test performance of some typical operations, run with:
    32  // N=1000000 go test -v ./... -run=TestPerformance
    33  // Iy you change anything here, change TestPerformance_plain too!
    34  func TestPerformance_reflection(t *testing.T) {
    35  	t.Parallel()
    36  	n := performanceN(os.Getenv("N"))
    37  	defer stopwatch(n, "WITH REFLECTION")()
    38  	for i := 0; i < n; i++ {
    39  		p := &Person{}
    40  		obj := New(p)
    41  
    42  		err := obj.Field("Number").Set(i)
    43  		if err != nil {
    44  			t.Fatal("Should not error")
    45  		}
    46  		if p.Number != i {
    47  			t.Fatalf("Should be %d", i)
    48  		}
    49  		number, err := obj.Field("Number").Get()
    50  		if err != nil {
    51  			t.Fatal("Number is valid")
    52  		}
    53  		if number.(int) != i {
    54  			t.Fatalf("Should be %d", i)
    55  		}
    56  		res, err := obj.Method("Add").Call(1, 2, 3)
    57  		if err != nil {
    58  			t.Fatal("shouldn't be an error")
    59  		}
    60  		if res.IsError() {
    61  			t.Fatal("method shouldn't return an error")
    62  		}
    63  		if len(res.Result) != 1 && res.Result[0].(int) != 6 {
    64  			t.Fatal("result should be 6")
    65  		}
    66  	}
    67  }
    68  
    69  func TestPerformance_plain(t *testing.T) {
    70  	t.Parallel()
    71  	n := performanceN(os.Getenv("N"))
    72  	defer stopwatch(n, "WITHOUT REFLECTION")()
    73  	for i := 0; i < n; i++ {
    74  		p := &Person{}
    75  
    76  		p.Number = i
    77  		number := p.Number
    78  		if number != i {
    79  			t.Fatalf("Should be %d", i)
    80  		}
    81  		res := p.Add(1, 2, 3)
    82  		if res != 6 {
    83  			t.Fatal("result should be 6")
    84  		}
    85  	}
    86  }