837 lines
19 KiB
Go
837 lines
19 KiB
Go
package factions
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
// Benchmark MasterFactionList operations
|
|
func BenchmarkMasterFactionList(b *testing.B) {
|
|
b.Run("GetFaction", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
// Pre-populate with factions
|
|
for i := int32(1); i <= 1000; i++ {
|
|
faction := NewFaction(i, "Benchmark Faction", "Test", "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 1000) + 1)
|
|
_ = mfl.GetFaction(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("GetFactionByName", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
// Pre-populate with factions
|
|
for i := int32(1); i <= 1000; i++ {
|
|
faction := NewFaction(i, "Benchmark Faction", "Test", "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetFactionByName("Benchmark Faction")
|
|
}
|
|
})
|
|
|
|
b.Run("AddFaction", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
// Pre-populate with factions
|
|
for i := int32(1); i <= 1000; i++ {
|
|
faction := NewFaction(i, "Benchmark Faction", "Test", "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32(2000 + i)
|
|
faction := NewFaction(factionID, "New Faction", "Test", "New test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
})
|
|
|
|
b.Run("GetFactionCount", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
// Pre-populate with factions
|
|
for i := int32(1); i <= 1000; i++ {
|
|
faction := NewFaction(i, "Benchmark Faction", "Test", "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetFactionCount()
|
|
}
|
|
})
|
|
|
|
b.Run("AddHostileFaction", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
// Pre-populate with factions
|
|
for i := int32(1); i <= 1000; i++ {
|
|
faction := NewFaction(i, "Benchmark Faction", "Test", "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 1000) + 1)
|
|
hostileID := int32(((i + 1) % 1000) + 1)
|
|
mfl.AddHostileFaction(factionID, hostileID)
|
|
}
|
|
})
|
|
|
|
b.Run("GetHostileFactions", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
// Pre-populate with factions and some hostile relationships
|
|
for i := int32(1); i <= 1000; i++ {
|
|
faction := NewFaction(i, "Benchmark Faction", "Test", "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
// Add a reasonable number of hostile relationships
|
|
for i := int32(1); i <= 100; i++ {
|
|
for j := int32(1); j <= 5; j++ {
|
|
mfl.AddHostileFaction(i, i+j)
|
|
}
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
_ = mfl.GetHostileFactions(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("ValidateFactions", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
// Pre-populate with factions
|
|
for i := int32(1); i <= 1000; i++ {
|
|
faction := NewFaction(i, "Benchmark Faction", "Test", "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
// Add some hostile relationships for realistic validation
|
|
for i := int32(1); i <= 100; i++ {
|
|
mfl.AddHostileFaction(i, i+1)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.ValidateFactions()
|
|
}
|
|
})
|
|
}
|
|
|
|
// Benchmark PlayerFaction operations
|
|
func BenchmarkPlayerFaction(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
// Setup factions with proper values
|
|
for i := int32(1); i <= 100; i++ {
|
|
faction := NewFaction(i, "Player Faction", "Test", "Player test")
|
|
faction.PositiveChange = 100
|
|
faction.NegativeChange = 50
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
pf := NewPlayerFaction(mfl)
|
|
|
|
// Pre-populate some faction values
|
|
for i := int32(1); i <= 100; i++ {
|
|
pf.SetFactionValue(i, int32(i*1000))
|
|
}
|
|
|
|
b.Run("GetFactionValue", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
_ = pf.GetFactionValue(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("SetFactionValue", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
pf.SetFactionValue(factionID, int32(i))
|
|
}
|
|
})
|
|
|
|
b.Run("IncreaseFaction", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
pf.IncreaseFaction(factionID, 10)
|
|
}
|
|
})
|
|
|
|
b.Run("DecreaseFaction", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
pf.DecreaseFaction(factionID, 5)
|
|
}
|
|
})
|
|
|
|
b.Run("GetCon", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
_ = pf.GetCon(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("GetPercent", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
_ = pf.GetPercent(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("ShouldAttack", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
_ = pf.ShouldAttack(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("FactionUpdate", func(b *testing.B) {
|
|
// Trigger some updates first
|
|
for i := int32(1); i <= 10; i++ {
|
|
pf.IncreaseFaction(i, 1)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
pf.FactionUpdate(int16(i % 10))
|
|
}
|
|
})
|
|
}
|
|
|
|
// Benchmark Manager operations
|
|
func BenchmarkManager(b *testing.B) {
|
|
manager := NewManager(nil, nil)
|
|
|
|
// Pre-populate with factions
|
|
for i := int32(1); i <= 100; i++ {
|
|
faction := NewFaction(i, "Manager Faction", "Test", "Manager test")
|
|
manager.AddFaction(faction)
|
|
}
|
|
|
|
b.Run("GetFaction", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
_ = manager.GetFaction(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("CreatePlayerFaction", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = manager.CreatePlayerFaction()
|
|
}
|
|
})
|
|
|
|
b.Run("RecordFactionIncrease", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
manager.RecordFactionIncrease(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("RecordFactionDecrease", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 100) + 1)
|
|
manager.RecordFactionDecrease(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("GetStatistics", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = manager.GetStatistics()
|
|
}
|
|
})
|
|
|
|
b.Run("ValidateAllFactions", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = manager.ValidateAllFactions()
|
|
}
|
|
})
|
|
}
|
|
|
|
// Benchmark EntityFactionAdapter operations
|
|
func BenchmarkEntityFactionAdapter(b *testing.B) {
|
|
manager := NewManager(nil, nil)
|
|
entity := &mockEntity{id: 123, name: "Benchmark Entity", dbID: 456}
|
|
adapter := NewEntityFactionAdapter(entity, manager, nil)
|
|
|
|
// Set up factions and relationships
|
|
for i := int32(1); i <= 10; i++ {
|
|
faction := NewFaction(i, "Entity Faction", "Test", "Entity test")
|
|
manager.AddFaction(faction)
|
|
}
|
|
|
|
mfl := manager.GetMasterFactionList()
|
|
mfl.AddHostileFaction(1, 2)
|
|
mfl.AddFriendlyFaction(1, 3)
|
|
|
|
b.Run("GetFactionID", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = adapter.GetFactionID()
|
|
}
|
|
})
|
|
|
|
b.Run("SetFactionID", func(b *testing.B) {
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 10) + 1)
|
|
adapter.SetFactionID(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("GetFaction", func(b *testing.B) {
|
|
adapter.SetFactionID(1)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = adapter.GetFaction()
|
|
}
|
|
})
|
|
|
|
b.Run("IsHostileToFaction", func(b *testing.B) {
|
|
adapter.SetFactionID(1)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
targetID := int32((i % 10) + 1)
|
|
_ = adapter.IsHostileToFaction(targetID)
|
|
}
|
|
})
|
|
|
|
b.Run("IsFriendlyToFaction", func(b *testing.B) {
|
|
adapter.SetFactionID(1)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
targetID := int32((i % 10) + 1)
|
|
_ = adapter.IsFriendlyToFaction(targetID)
|
|
}
|
|
})
|
|
|
|
b.Run("ValidateFaction", func(b *testing.B) {
|
|
adapter.SetFactionID(1)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = adapter.ValidateFaction()
|
|
}
|
|
})
|
|
}
|
|
|
|
// Benchmark concurrent operations
|
|
func BenchmarkConcurrentOperations(b *testing.B) {
|
|
b.Run("MasterFactionListConcurrent", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
// Pre-populate
|
|
for i := int32(1); i <= 100; i++ {
|
|
faction := NewFaction(i, "Concurrent Faction", "Test", "Concurrent test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
factionID := int32((i % 100) + 1)
|
|
_ = mfl.GetFaction(factionID)
|
|
i++
|
|
}
|
|
})
|
|
})
|
|
|
|
b.Run("PlayerFactionConcurrent", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
for i := int32(1); i <= 10; i++ {
|
|
faction := NewFaction(i, "Player Faction", "Test", "Player test")
|
|
faction.PositiveChange = 100
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
pf := NewPlayerFaction(mfl)
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
factionID := int32((i % 10) + 1)
|
|
switch i % 4 {
|
|
case 0:
|
|
_ = pf.GetFactionValue(factionID)
|
|
case 1:
|
|
pf.IncreaseFaction(factionID, 1)
|
|
case 2:
|
|
_ = pf.GetCon(factionID)
|
|
case 3:
|
|
_ = pf.GetPercent(factionID)
|
|
}
|
|
i++
|
|
}
|
|
})
|
|
})
|
|
|
|
b.Run("ManagerConcurrent", func(b *testing.B) {
|
|
manager := NewManager(nil, nil)
|
|
|
|
// Pre-populate
|
|
for i := int32(1); i <= 10; i++ {
|
|
faction := NewFaction(i, "Manager Faction", "Test", "Manager test")
|
|
manager.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
factionID := int32((i % 10) + 1)
|
|
switch i % 4 {
|
|
case 0:
|
|
_ = manager.GetFaction(factionID)
|
|
case 1:
|
|
manager.RecordFactionIncrease(factionID)
|
|
case 2:
|
|
_ = manager.GetStatistics()
|
|
case 3:
|
|
_ = manager.CreatePlayerFaction()
|
|
}
|
|
i++
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
// Memory allocation benchmarks
|
|
func BenchmarkMemoryAllocations(b *testing.B) {
|
|
b.Run("FactionCreation", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = NewFaction(int32(i), "Memory Test", "Test", "Memory test")
|
|
}
|
|
})
|
|
|
|
b.Run("MasterFactionListCreation", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = NewMasterList()
|
|
}
|
|
})
|
|
|
|
b.Run("PlayerFactionCreation", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = NewPlayerFaction(mfl)
|
|
}
|
|
})
|
|
|
|
b.Run("ManagerCreation", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = NewManager(nil, nil)
|
|
}
|
|
})
|
|
|
|
b.Run("EntityAdapterCreation", func(b *testing.B) {
|
|
manager := NewManager(nil, nil)
|
|
entity := &mockEntity{id: 123, name: "Memory Entity", dbID: 456}
|
|
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = NewEntityFactionAdapter(entity, manager, nil)
|
|
}
|
|
})
|
|
}
|
|
|
|
// Contention benchmarks
|
|
func BenchmarkContention(b *testing.B) {
|
|
b.Run("HighContentionReads", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
// Add a single faction that will be accessed heavily
|
|
faction := NewFaction(1, "Contention Test", "Test", "Contention test")
|
|
mfl.AddFaction(faction)
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
_ = mfl.GetFaction(1)
|
|
}
|
|
})
|
|
})
|
|
|
|
b.Run("HighContentionWrites", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
factionID := int32(1000000 + i) // Unique IDs to avoid conflicts
|
|
faction := NewFaction(factionID, "Write Test", "Test", "Write test")
|
|
mfl.AddFaction(faction)
|
|
i++
|
|
}
|
|
})
|
|
})
|
|
|
|
b.Run("MixedReadWrite", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
// Pre-populate
|
|
for i := int32(1); i <= 100; i++ {
|
|
faction := NewFaction(i, "Mixed Test", "Test", "Mixed test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
if i%10 == 0 {
|
|
// 10% writes
|
|
factionID := int32(2000000 + i)
|
|
faction := NewFaction(factionID, "New Mixed", "Test", "New mixed")
|
|
mfl.AddFaction(faction)
|
|
} else {
|
|
// 90% reads
|
|
factionID := int32((i % 100) + 1)
|
|
_ = mfl.GetFaction(factionID)
|
|
}
|
|
i++
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
// Scalability benchmarks
|
|
func BenchmarkScalability(b *testing.B) {
|
|
sizes := []int{10, 100, 1000, 10000}
|
|
|
|
for _, size := range sizes {
|
|
b.Run("FactionLookup_"+string(rune(size)), func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
// Pre-populate with varying sizes
|
|
for i := int32(1); i <= int32(size); i++ {
|
|
faction := NewFaction(i, "Scale Test", "Test", "Scale test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % size) + 1)
|
|
_ = mfl.GetFaction(factionID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Benchmark bespoke MasterList features
|
|
func BenchmarkMasterListBespokeFeatures(b *testing.B) {
|
|
// Setup function for consistent test data
|
|
setupMasterList := func() *MasterList {
|
|
mfl := NewMasterList()
|
|
|
|
// Add factions across different types
|
|
types := []string{"City", "Guild", "Religion", "Race", "Organization"}
|
|
|
|
for i := 1; i <= 1000; i++ {
|
|
factionType := types[i%len(types)]
|
|
faction := NewFaction(int32(i), fmt.Sprintf("Faction%d", i), factionType, "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
return mfl
|
|
}
|
|
|
|
b.Run("GetFactionSafe", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 1000) + 1)
|
|
_, _ = mfl.GetFactionSafe(factionID)
|
|
}
|
|
})
|
|
|
|
b.Run("GetFactionByName", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
names := []string{"faction1", "faction50", "faction100", "faction500", "faction1000"}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
name := names[i%len(names)]
|
|
_ = mfl.GetFactionByName(name)
|
|
}
|
|
})
|
|
|
|
b.Run("GetFactionsByType", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
types := []string{"City", "Guild", "Religion", "Race", "Organization"}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionType := types[i%len(types)]
|
|
_ = mfl.GetFactionsByType(factionType)
|
|
}
|
|
})
|
|
|
|
b.Run("GetSpecialFactions", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
// Add some special factions
|
|
for i := int32(1); i <= 5; i++ {
|
|
faction := NewFaction(i, fmt.Sprintf("Special%d", i), "Special", "Special faction")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetSpecialFactions()
|
|
}
|
|
})
|
|
|
|
b.Run("GetRegularFactions", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetRegularFactions()
|
|
}
|
|
})
|
|
|
|
b.Run("GetTypes", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetTypes()
|
|
}
|
|
})
|
|
|
|
b.Run("GetAllFactionsList", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetAllFactionsList()
|
|
}
|
|
})
|
|
|
|
b.Run("GetFactionIDs", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetFactionIDs()
|
|
}
|
|
})
|
|
|
|
b.Run("UpdateFaction", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
factionID := int32((i % 1000) + 1)
|
|
updatedFaction := &Faction{
|
|
ID: factionID,
|
|
Name: fmt.Sprintf("Updated%d", i),
|
|
Type: "Updated",
|
|
Description: "Updated faction",
|
|
}
|
|
mfl.UpdateFaction(updatedFaction)
|
|
}
|
|
})
|
|
|
|
b.Run("ForEach", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
count := 0
|
|
mfl.ForEach(func(id int32, faction *Faction) {
|
|
count++
|
|
})
|
|
}
|
|
})
|
|
|
|
b.Run("GetStatistics", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetStatistics()
|
|
}
|
|
})
|
|
|
|
b.Run("RemoveFaction", func(b *testing.B) {
|
|
b.StopTimer()
|
|
mfl := setupMasterList()
|
|
initialCount := mfl.GetFactionCount()
|
|
|
|
// Pre-populate with factions we'll remove
|
|
for i := 0; i < b.N; i++ {
|
|
faction := NewFaction(int32(20000+i), fmt.Sprintf("ToRemove%d", i), "Temporary", "Temporary faction")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.StartTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
mfl.RemoveFaction(int32(20000 + i))
|
|
}
|
|
|
|
b.StopTimer()
|
|
if mfl.GetFactionCount() != initialCount {
|
|
b.Errorf("Expected %d factions after removal, got %d", initialCount, mfl.GetFactionCount())
|
|
}
|
|
})
|
|
}
|
|
|
|
// Memory allocation benchmarks for bespoke features
|
|
func BenchmarkMasterListBespokeFeatures_Allocs(b *testing.B) {
|
|
setupMasterList := func() *MasterList {
|
|
mfl := NewMasterList()
|
|
types := []string{"City", "Guild", "Religion", "Race", "Organization"}
|
|
|
|
for i := 1; i <= 100; i++ {
|
|
factionType := types[i%len(types)]
|
|
faction := NewFaction(int32(i), fmt.Sprintf("Faction%d", i), factionType, "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
return mfl
|
|
}
|
|
|
|
b.Run("GetFactionByName_Allocs", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetFactionByName("faction1")
|
|
}
|
|
})
|
|
|
|
b.Run("GetFactionsByType_Allocs", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetFactionsByType("City")
|
|
}
|
|
})
|
|
|
|
b.Run("GetTypes_Allocs", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetTypes()
|
|
}
|
|
})
|
|
|
|
b.Run("GetSpecialFactions_Allocs", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
// Add some special factions
|
|
for i := int32(1); i <= 5; i++ {
|
|
faction := NewFaction(i, fmt.Sprintf("Special%d", i), "Special", "Special faction")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetSpecialFactions()
|
|
}
|
|
})
|
|
|
|
b.Run("GetStatistics_Allocs", func(b *testing.B) {
|
|
mfl := setupMasterList()
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = mfl.GetStatistics()
|
|
}
|
|
})
|
|
}
|
|
|
|
// Concurrent benchmarks for bespoke features
|
|
func BenchmarkMasterListBespokeConcurrent(b *testing.B) {
|
|
b.Run("ConcurrentReads", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
// Setup test data
|
|
types := []string{"City", "Guild", "Religion", "Race", "Organization"}
|
|
for i := 1; i <= 100; i++ {
|
|
factionType := types[i%len(types)]
|
|
faction := NewFaction(int32(i), fmt.Sprintf("Faction%d", i), factionType, "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
// Mix of read operations
|
|
switch i % 6 {
|
|
case 0:
|
|
mfl.GetFaction(int32(i%100 + 1))
|
|
case 1:
|
|
mfl.GetFactionsByType("City")
|
|
case 2:
|
|
mfl.GetFactionByName("faction1")
|
|
case 3:
|
|
mfl.GetSpecialFactions()
|
|
case 4:
|
|
mfl.GetRegularFactions()
|
|
case 5:
|
|
mfl.GetTypes()
|
|
}
|
|
i++
|
|
}
|
|
})
|
|
})
|
|
|
|
b.Run("ConcurrentMixed", func(b *testing.B) {
|
|
mfl := NewMasterList()
|
|
|
|
// Setup test data
|
|
types := []string{"City", "Guild", "Religion", "Race", "Organization"}
|
|
for i := 1; i <= 100; i++ {
|
|
factionType := types[i%len(types)]
|
|
faction := NewFaction(int32(i), fmt.Sprintf("Faction%d", i), factionType, "Benchmark test")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
// Mix of read and write operations (mostly reads)
|
|
switch i % 10 {
|
|
case 0: // 10% writes
|
|
faction := NewFaction(int32(i+50000), fmt.Sprintf("Concurrent%d", i), "Concurrent", "Concurrent test")
|
|
mfl.AddFaction(faction)
|
|
default: // 90% reads
|
|
switch i % 5 {
|
|
case 0:
|
|
mfl.GetFaction(int32(i%100 + 1))
|
|
case 1:
|
|
mfl.GetFactionsByType("City")
|
|
case 2:
|
|
mfl.GetFactionByName("faction1")
|
|
case 3:
|
|
mfl.GetSpecialFactions()
|
|
case 4:
|
|
mfl.GetTypes()
|
|
}
|
|
}
|
|
i++
|
|
}
|
|
})
|
|
})
|
|
}
|