Skip to content

Commit d4b8029

Browse files
author
OpenClaw
committed
feat(example): add new example directories
- benchmark: performance testing examples - map: Map ↔ Struct conversion examples - slice: batch mapping advanced examples - config: configuration options examples - error: error handling scenarios examples
1 parent 17e89d5 commit d4b8029

5 files changed

Lines changed: 852 additions & 84 deletions

File tree

example/benchmark/main.go

Lines changed: 190 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2,110 +2,216 @@ package main
22

33
import (
44
"fmt"
5-
"time"
5+
"testing"
66

77
"github.com/devfeel/mapper"
88
)
99

10-
// Test structs with 10 fields
11-
type Source struct {
12-
Name string
13-
Age int
14-
Email string
15-
Phone string
16-
Address string
17-
City string
18-
Country string
19-
ZipCode string
20-
Status int
21-
Score float64
10+
// 测试用结构体
11+
type (
12+
BenchUser struct {
13+
ID int64 `mapper:"id"`
14+
Name string `mapper:"name"`
15+
Email string `mapper:"email"`
16+
Age int `mapper:"age"`
17+
CreatedAt int64 `mapper:"created_at"`
18+
Score float64
19+
}
20+
21+
BenchUserDTO struct {
22+
ID int64 `json:"id"`
23+
Name string `json:"name"`
24+
Email string `json:"email"`
25+
Age int `json:"age"`
26+
CreatedAt int64 `json:"created_at"`
27+
Score float64 `json:"score"`
28+
}
29+
)
30+
31+
// Benchmark_MapDirect_1000 benchmark for MapDirect with 1000 iterations
32+
func Benchmark_MapDirect_1000(b *testing.B) {
33+
user := BenchUser{
34+
ID: 1,
35+
Name: "Test User",
36+
Email: "test@example.com",
37+
Age: 25,
38+
CreatedAt: 1704067200,
39+
Score: 95.5,
40+
}
41+
42+
b.ResetTimer()
43+
for i := 0; i < b.N; i++ {
44+
_ = mapper.MapDirect[BenchUser, BenchUserDTO](user)
45+
}
2246
}
2347

24-
type Dest struct {
25-
Name string
26-
Age int
27-
Email string
28-
Phone string
29-
Address string
30-
City string
31-
Country string
32-
ZipCode string
33-
Status int
34-
Score float64
48+
// Benchmark_MapDirectSlice_10 benchmark for MapDirectSlice with 10 items
49+
func Benchmark_MapDirectSlice_10(b *testing.B) {
50+
users := make([]BenchUser, 10)
51+
for i := 0; i < 10; i++ {
52+
users[i] = BenchUser{
53+
ID: int64(i),
54+
Name: "User",
55+
Email: "test@example.com",
56+
Age: 25,
57+
CreatedAt: 1704067200,
58+
Score: 95.5,
59+
}
60+
}
61+
62+
b.ResetTimer()
63+
for i := 0; i < b.N; i++ {
64+
_ = mapper.MapDirectSlice[BenchUser, BenchUserDTO](users)
65+
}
3566
}
3667

37-
func main() {
38-
// Create test data
39-
src := &Source{
40-
Name: "test",
41-
Age: 25,
42-
Email: "test@example.com",
43-
Phone: "1234567890",
44-
Address: "123 Test St",
45-
City: "TestCity",
46-
Country: "TestCountry",
47-
ZipCode: "12345",
48-
Status: 1,
49-
Score: 95.5,
50-
}
51-
52-
// Test 1: Single mapping
53-
fmt.Println("=== Test 1: Single Mapping ===")
54-
start := time.Now()
68+
// Benchmark_MapDirectSlice_100 benchmark for MapDirectSlice with 100 items
69+
func Benchmark_MapDirectSlice_100(b *testing.B) {
70+
users := make([]BenchUser, 100)
71+
for i := 0; i < 100; i++ {
72+
users[i] = BenchUser{
73+
ID: int64(i),
74+
Name: "User",
75+
Email: "test@example.com",
76+
Age: 25,
77+
CreatedAt: 1704067200,
78+
Score: 95.5,
79+
}
80+
}
81+
82+
b.ResetTimer()
83+
for i := 0; i < b.N; i++ {
84+
_ = mapper.MapDirectSlice[BenchUser, BenchUserDTO](users)
85+
}
86+
}
87+
88+
// Benchmark_MapDirectSlice_1000 benchmark for MapDirectSlice with 1000 items
89+
func Benchmark_MapDirectSlice_1000(b *testing.B) {
90+
users := make([]BenchUser, 1000)
5591
for i := 0; i < 1000; i++ {
56-
dest := &Dest{}
57-
mapper.Mapper(src, dest)
92+
users[i] = BenchUser{
93+
ID: int64(i),
94+
Name: "User",
95+
Email: "test@example.com",
96+
Age: 25,
97+
CreatedAt: 1704067200,
98+
Score: 95.5,
99+
}
100+
}
101+
102+
b.ResetTimer()
103+
for i := 0; i < b.N; i++ {
104+
_ = mapper.MapDirectSlice[BenchUser, BenchUserDTO](users)
58105
}
59-
elapsed := time.Since(start)
60-
fmt.Printf("1000 single mappings: %v\n", elapsed)
61-
fmt.Printf("Average per mapping: %v\n", elapsed/time.Duration(1000))
106+
}
62107

63-
// Test 2: Slice mapping
64-
fmt.Println("\n=== Test 2: Slice Mapping ===")
65-
srcList := make([]Source, 100)
108+
// Benchmark_MapDirectPtrSlice_100 benchmark for MapDirectPtrSlice with 100 items
109+
func Benchmark_MapDirectPtrSlice_100(b *testing.B) {
110+
users := make([]*BenchUser, 100)
66111
for i := 0; i < 100; i++ {
67-
srcList[i] = Source{
68-
Name: "test",
69-
Age: 25,
70-
Email: "test@example.com",
71-
Phone: "1234567890",
72-
Address: "123 Test St",
73-
City: "TestCity",
74-
Country: "TestCountry",
75-
ZipCode: "12345",
76-
Status: 1,
77-
Score: 95.5,
112+
users[i] = &BenchUser{
113+
ID: int64(i),
114+
Name: "User",
115+
Email: "test@example.com",
116+
Age: 25,
117+
CreatedAt: 1704067200,
118+
Score: 95.5,
78119
}
79120
}
80121

81-
start = time.Now()
122+
b.ResetTimer()
123+
for i := 0; i < b.N; i++ {
124+
_ = mapper.MapDirectPtrSlice[BenchUser, BenchUserDTO](users)
125+
}
126+
}
127+
128+
// Benchmark_SafeMapDirect benchmark for SafeMapDirect
129+
func Benchmark_SafeMapDirect(b *testing.B) {
130+
user := BenchUser{
131+
ID: 1,
132+
Name: "Test User",
133+
Email: "test@example.com",
134+
Age: 25,
135+
CreatedAt: 1704067200,
136+
Score: 95.5,
137+
}
138+
139+
b.ResetTimer()
140+
for i := 0; i < b.N; i++ {
141+
_, _ = mapper.SafeMapDirect[BenchUser, BenchUserDTO](user)
142+
}
143+
}
144+
145+
// Benchmark_SafeMapDirectSlice_100 benchmark for SafeMapDirectSlice with 100 items
146+
func Benchmark_SafeMapDirectSlice_100(b *testing.B) {
147+
users := make([]BenchUser, 100)
82148
for i := 0; i < 100; i++ {
83-
var destList []Dest
84-
mapper.MapperSlice(srcList, &destList)
149+
users[i] = BenchUser{
150+
ID: int64(i),
151+
Name: "User",
152+
Email: "test@example.com",
153+
Age: 25,
154+
CreatedAt: 1704067200,
155+
Score: 95.5,
156+
}
85157
}
86-
elapsed = time.Since(start)
87-
fmt.Printf("100 slice mappings (100 items each): %v\n", elapsed)
88-
fmt.Printf("Average per slice: %v\n", elapsed/time.Duration(100))
89158

90-
// Test 3: Different types
91-
fmt.Println("\n=== Test 3: Different Type Pairs ===")
92-
type TypeA struct{ Name string }
93-
type TypeB struct{ Name string }
94-
type TypeC struct{ Value int }
95-
type TypeD struct{ Value int }
159+
b.ResetTimer()
160+
for i := 0; i < b.N; i++ {
161+
_, _ = mapper.SafeMapDirectSlice[BenchUser, BenchUserDTO](users)
162+
}
163+
}
96164

97-
start = time.Now()
98-
for i := 0; i < 1000; i++ {
99-
a := &TypeA{Name: "test"}
100-
b := &TypeB{}
101-
mapper.Mapper(a, b)
165+
// Benchmark_Old_Mapper benchmark for traditional Mapper
166+
func Benchmark_Old_Mapper(b *testing.B) {
167+
user := &BenchUser{
168+
ID: 1,
169+
Name: "Test User",
170+
Email: "test@example.com",
171+
Age: 25,
172+
CreatedAt: 1704067200,
173+
Score: 95.5,
174+
}
175+
userDTO := &BenchUserDTO{}
102176

103-
c := &TypeC{Value: 100}
104-
d := &TypeD{}
105-
mapper.Mapper(c, d)
177+
b.ResetTimer()
178+
for i := 0; i < b.N; i++ {
179+
_ = mapper.Mapper(user, userDTO)
106180
}
107-
elapsed = time.Since(start)
108-
fmt.Printf("1000 different type mappings: %v\n", elapsed)
181+
}
109182

110-
fmt.Println("\n=== All tests completed ===")
183+
// Benchmark_Old_MapperSlice benchmark for traditional MapperSlice
184+
func Benchmark_Old_MapperSlice(b *testing.B) {
185+
users := make([]BenchUser, 100)
186+
for i := 0; i < 100; i++ {
187+
users[i] = BenchUser{
188+
ID: int64(i),
189+
Name: "User",
190+
Email: "test@example.com",
191+
Age: 25,
192+
CreatedAt: 1704067200,
193+
Score: 95.5,
194+
}
195+
}
196+
userDTOs := &[]BenchUserDTO{}
197+
198+
b.ResetTimer()
199+
for i := 0; i < b.N; i++ {
200+
_ = mapper.MapperSlice(users, userDTOs)
201+
}
202+
}
203+
204+
// 运行示例
205+
func main() {
206+
fmt.Println("=== Mapper 性能测试示例 ===")
207+
fmt.Println()
208+
fmt.Println("运行基准测试:")
209+
fmt.Println(" go test -bench=Benchmark -benchmem ./benchmark/")
210+
fmt.Println()
211+
fmt.Println("运行特定测试:")
212+
fmt.Println(" go test -bench=MapDirectSlice_100 -benchmem ./benchmark/")
213+
fmt.Println()
214+
fmt.Println("示例输出:")
215+
fmt.Println(" Benchmark_MapDirectSlice_100-8 20000 58000 ns/op")
216+
fmt.Println(" 说明: 每次映射 100 条数据,耗时约 58 微秒")
111217
}

0 commit comments

Comments
 (0)