Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
274 changes: 190 additions & 84 deletions example/benchmark/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,110 +2,216 @@ package main

import (
"fmt"
"time"
"testing"

"github.com/devfeel/mapper"
)

// Test structs with 10 fields
type Source struct {
Name string
Age int
Email string
Phone string
Address string
City string
Country string
ZipCode string
Status int
Score float64
// 测试用结构体
type (
BenchUser struct {
ID int64 `mapper:"id"`
Name string `mapper:"name"`
Email string `mapper:"email"`
Age int `mapper:"age"`
CreatedAt int64 `mapper:"created_at"`
Score float64
}

BenchUserDTO struct {
ID int64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
CreatedAt int64 `json:"created_at"`
Score float64 `json:"score"`
}
)

// Benchmark_MapDirect_1000 benchmark for MapDirect with 1000 iterations
func Benchmark_MapDirect_1000(b *testing.B) {
user := BenchUser{
ID: 1,
Name: "Test User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper.MapDirect[BenchUser, BenchUserDTO](user)
}
}

type Dest struct {
Name string
Age int
Email string
Phone string
Address string
City string
Country string
ZipCode string
Status int
Score float64
// Benchmark_MapDirectSlice_10 benchmark for MapDirectSlice with 10 items
func Benchmark_MapDirectSlice_10(b *testing.B) {
users := make([]BenchUser, 10)
for i := 0; i < 10; i++ {
users[i] = BenchUser{
ID: int64(i),
Name: "User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper.MapDirectSlice[BenchUser, BenchUserDTO](users)
}
}

func main() {
// Create test data
src := &Source{
Name: "test",
Age: 25,
Email: "test@example.com",
Phone: "1234567890",
Address: "123 Test St",
City: "TestCity",
Country: "TestCountry",
ZipCode: "12345",
Status: 1,
Score: 95.5,
}

// Test 1: Single mapping
fmt.Println("=== Test 1: Single Mapping ===")
start := time.Now()
// Benchmark_MapDirectSlice_100 benchmark for MapDirectSlice with 100 items
func Benchmark_MapDirectSlice_100(b *testing.B) {
users := make([]BenchUser, 100)
for i := 0; i < 100; i++ {
users[i] = BenchUser{
ID: int64(i),
Name: "User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper.MapDirectSlice[BenchUser, BenchUserDTO](users)
}
}

// Benchmark_MapDirectSlice_1000 benchmark for MapDirectSlice with 1000 items
func Benchmark_MapDirectSlice_1000(b *testing.B) {
users := make([]BenchUser, 1000)
for i := 0; i < 1000; i++ {
dest := &Dest{}
mapper.Mapper(src, dest)
users[i] = BenchUser{
ID: int64(i),
Name: "User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper.MapDirectSlice[BenchUser, BenchUserDTO](users)
}
elapsed := time.Since(start)
fmt.Printf("1000 single mappings: %v\n", elapsed)
fmt.Printf("Average per mapping: %v\n", elapsed/time.Duration(1000))
}

// Test 2: Slice mapping
fmt.Println("\n=== Test 2: Slice Mapping ===")
srcList := make([]Source, 100)
// Benchmark_MapDirectPtrSlice_100 benchmark for MapDirectPtrSlice with 100 items
func Benchmark_MapDirectPtrSlice_100(b *testing.B) {
users := make([]*BenchUser, 100)
for i := 0; i < 100; i++ {
srcList[i] = Source{
Name: "test",
Age: 25,
Email: "test@example.com",
Phone: "1234567890",
Address: "123 Test St",
City: "TestCity",
Country: "TestCountry",
ZipCode: "12345",
Status: 1,
Score: 95.5,
users[i] = &BenchUser{
ID: int64(i),
Name: "User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}
}

start = time.Now()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper.MapDirectPtrSlice[BenchUser, BenchUserDTO](users)
}
}

// Benchmark_SafeMapDirect benchmark for SafeMapDirect
func Benchmark_SafeMapDirect(b *testing.B) {
user := BenchUser{
ID: 1,
Name: "Test User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = mapper.SafeMapDirect[BenchUser, BenchUserDTO](user)
}
}

// Benchmark_SafeMapDirectSlice_100 benchmark for SafeMapDirectSlice with 100 items
func Benchmark_SafeMapDirectSlice_100(b *testing.B) {
users := make([]BenchUser, 100)
for i := 0; i < 100; i++ {
var destList []Dest
mapper.MapperSlice(srcList, &destList)
users[i] = BenchUser{
ID: int64(i),
Name: "User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}
}
elapsed = time.Since(start)
fmt.Printf("100 slice mappings (100 items each): %v\n", elapsed)
fmt.Printf("Average per slice: %v\n", elapsed/time.Duration(100))

// Test 3: Different types
fmt.Println("\n=== Test 3: Different Type Pairs ===")
type TypeA struct{ Name string }
type TypeB struct{ Name string }
type TypeC struct{ Value int }
type TypeD struct{ Value int }
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = mapper.SafeMapDirectSlice[BenchUser, BenchUserDTO](users)
}
}

start = time.Now()
for i := 0; i < 1000; i++ {
a := &TypeA{Name: "test"}
b := &TypeB{}
mapper.Mapper(a, b)
// Benchmark_Old_Mapper benchmark for traditional Mapper
func Benchmark_Old_Mapper(b *testing.B) {
user := &BenchUser{
ID: 1,
Name: "Test User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}
userDTO := &BenchUserDTO{}

c := &TypeC{Value: 100}
d := &TypeD{}
mapper.Mapper(c, d)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper.Mapper(user, userDTO)
}
elapsed = time.Since(start)
fmt.Printf("1000 different type mappings: %v\n", elapsed)
}

fmt.Println("\n=== All tests completed ===")
// Benchmark_Old_MapperSlice benchmark for traditional MapperSlice
func Benchmark_Old_MapperSlice(b *testing.B) {
users := make([]BenchUser, 100)
for i := 0; i < 100; i++ {
users[i] = BenchUser{
ID: int64(i),
Name: "User",
Email: "test@example.com",
Age: 25,
CreatedAt: 1704067200,
Score: 95.5,
}
}
userDTOs := &[]BenchUserDTO{}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = mapper.MapperSlice(users, userDTOs)
}
}

// 运行示例
func main() {
fmt.Println("=== Mapper 性能测试示例 ===")
fmt.Println()
fmt.Println("运行基准测试:")
fmt.Println(" go test -bench=Benchmark -benchmem ./benchmark/")
fmt.Println()
fmt.Println("运行特定测试:")
fmt.Println(" go test -bench=MapDirectSlice_100 -benchmem ./benchmark/")
fmt.Println()
fmt.Println("示例输出:")
fmt.Println(" Benchmark_MapDirectSlice_100-8 20000 58000 ns/op")
fmt.Println(" 说明: 每次映射 100 条数据,耗时约 58 微秒")
}
Loading
Loading