456 lines
11 KiB
Go
456 lines
11 KiB
Go
package collections
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"eq2emu/internal/database"
|
|
)
|
|
|
|
// Setup creates a master list with test data for benchmarking
|
|
func benchmarkSetup() *MasterList {
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
|
|
masterList := NewMasterList()
|
|
|
|
// Add collections across different categories and levels
|
|
categories := []string{
|
|
"Heritage", "Treasured", "Legendary", "Fabled", "Mythical",
|
|
"Handcrafted", "Mastercrafted", "Rare", "Uncommon", "Common",
|
|
}
|
|
|
|
for i := 0; i < 100; i++ {
|
|
category := categories[i%len(categories)]
|
|
level := int8((i % 50) + 1) // Levels 1-50
|
|
|
|
collection := NewWithData(int32(i+1), fmt.Sprintf("Collection %d", i+1), category, level, db)
|
|
|
|
// Add collection items (some found, some not)
|
|
numItems := (i % 5) + 1 // 1-5 items per collection
|
|
for j := 0; j < numItems; j++ {
|
|
found := ItemNotFound
|
|
if (i+j)%3 == 0 { // About 1/3 of items are found
|
|
found = ItemFound
|
|
}
|
|
collection.CollectionItems = append(collection.CollectionItems, CollectionItem{
|
|
ItemID: int32((i+1)*1000 + j + 1),
|
|
Index: int8(j),
|
|
Found: int8(found),
|
|
})
|
|
}
|
|
|
|
// Add rewards
|
|
if i%4 == 0 {
|
|
collection.RewardCoin = int64((i + 1) * 100)
|
|
}
|
|
if i%5 == 0 {
|
|
collection.RewardXP = int64((i + 1) * 50)
|
|
}
|
|
if i%6 == 0 {
|
|
collection.RewardItems = append(collection.RewardItems, CollectionRewardItem{
|
|
ItemID: int32(i + 10000),
|
|
Quantity: 1,
|
|
})
|
|
}
|
|
if i%7 == 0 {
|
|
collection.SelectableRewardItems = append(collection.SelectableRewardItems, CollectionRewardItem{
|
|
ItemID: int32(i + 20000),
|
|
Quantity: 1,
|
|
})
|
|
}
|
|
|
|
// Some collections are completed
|
|
if i%10 == 0 {
|
|
collection.Completed = true
|
|
}
|
|
|
|
masterList.AddCollection(collection)
|
|
}
|
|
|
|
return masterList
|
|
}
|
|
|
|
func BenchmarkMasterList_AddCollection(b *testing.B) {
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
defer db.Close()
|
|
|
|
masterList := NewMasterList()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
collection := NewWithData(int32(i+10000), fmt.Sprintf("Collection%d", i), "Heritage", 20, db)
|
|
collection.CollectionItems = []CollectionItem{
|
|
{ItemID: int32(i + 50000), Index: 0, Found: ItemNotFound},
|
|
}
|
|
masterList.AddCollection(collection)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollection(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCollection(int32(i%100 + 1))
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollectionSafe(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCollectionSafe(int32(i%100 + 1))
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_HasCollection(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.HasCollection(int32(i%100 + 1))
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_FindCollectionsByCategory(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
categories := []string{"Heritage", "Treasured", "Legendary", "Fabled", "Mythical"}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.FindCollectionsByCategory(categories[i%len(categories)])
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollectionsByExactLevel(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
level := int8(i%50 + 1)
|
|
masterList.GetCollectionsByExactLevel(level)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_FindCollectionsByLevel(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
minLevel := int8(i%45 + 1)
|
|
maxLevel := minLevel + 5
|
|
masterList.FindCollectionsByLevel(minLevel, maxLevel)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollectionByName(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
names := []string{"collection 1", "collection 25", "collection 50", "collection 75", "collection 100"}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCollectionByName(names[i%len(names)])
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_NeedsItem(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
itemID := int32(i%100*1000 + 1001) // Various item IDs from the collections
|
|
masterList.NeedsItem(itemID)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollectionsNeedingItem(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
itemID := int32(i%100*1000 + 1001) // Various item IDs from the collections
|
|
masterList.GetCollectionsNeedingItem(itemID)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCompletedCollections(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCompletedCollections()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetIncompleteCollections(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetIncompleteCollections()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetReadyToTurnInCollections(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetReadyToTurnInCollections()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCategories(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCategories()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetLevels(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetLevels()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetItemsNeeded(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetItemsNeeded()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetAllCollections(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetAllCollections()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetAllCollectionsList(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetAllCollectionsList()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetStatistics(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetStatistics()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_ValidateCollections(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.ValidateCollections()
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_RemoveCollection(b *testing.B) {
|
|
b.StopTimer()
|
|
masterList := benchmarkSetup()
|
|
initialCount := masterList.GetCollectionCount()
|
|
|
|
// Pre-populate with collections we'll remove
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
for i := 0; i < b.N; i++ {
|
|
collection := NewWithData(int32(20000+i), fmt.Sprintf("ToRemove%d", i), "Temporary", 1, db)
|
|
collection.CollectionItems = []CollectionItem{
|
|
{ItemID: int32(60000 + i), Index: 0, Found: ItemNotFound},
|
|
}
|
|
masterList.AddCollection(collection)
|
|
}
|
|
|
|
b.StartTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.RemoveCollection(int32(20000 + i))
|
|
}
|
|
|
|
b.StopTimer()
|
|
if masterList.GetCollectionCount() != initialCount {
|
|
b.Errorf("Expected %d collections after removal, got %d", initialCount, masterList.GetCollectionCount())
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_ForEach(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
count := 0
|
|
masterList.ForEach(func(id int32, collection *Collection) {
|
|
count++
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_UpdateCollection(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
collectionID := int32(i%100 + 1)
|
|
updatedCollection := &Collection{
|
|
ID: collectionID,
|
|
Name: fmt.Sprintf("Updated%d", i),
|
|
Category: "Updated",
|
|
Level: 25,
|
|
db: db,
|
|
isNew: false,
|
|
CollectionItems: []CollectionItem{
|
|
{ItemID: int32(i + 70000), Index: 0, Found: ItemNotFound},
|
|
},
|
|
}
|
|
masterList.UpdateCollection(updatedCollection)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_RefreshCollectionIndices(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
collection := masterList.GetCollection(int32(i%100 + 1))
|
|
if collection != nil {
|
|
masterList.RefreshCollectionIndices(collection)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollectionClone(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCollectionClone(int32(i%100 + 1))
|
|
}
|
|
}
|
|
|
|
// Memory allocation benchmarks
|
|
func BenchmarkMasterList_GetCollection_Allocs(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCollection(int32(i%100 + 1))
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_FindCollectionsByCategory_Allocs(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.FindCollectionsByCategory("Heritage")
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollectionByName_Allocs(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCollectionByName("collection 1")
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_NeedsItem_Allocs(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.NeedsItem(1001)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterList_GetCollectionsNeedingItem_Allocs(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
masterList.GetCollectionsNeedingItem(1001)
|
|
}
|
|
}
|
|
|
|
// Concurrent benchmarks
|
|
func BenchmarkMasterList_ConcurrentReads(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
// Mix of read operations
|
|
switch b.N % 6 {
|
|
case 0:
|
|
masterList.GetCollection(int32(b.N%100 + 1))
|
|
case 1:
|
|
masterList.FindCollectionsByCategory("Heritage")
|
|
case 2:
|
|
masterList.GetCollectionByName("collection 1")
|
|
case 3:
|
|
masterList.NeedsItem(1001)
|
|
case 4:
|
|
masterList.GetCompletedCollections()
|
|
case 5:
|
|
masterList.GetCollectionsByExactLevel(10)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func BenchmarkMasterList_ConcurrentMixed(b *testing.B) {
|
|
masterList := benchmarkSetup()
|
|
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
// Mix of read and write operations (mostly reads)
|
|
switch b.N % 10 {
|
|
case 0: // 10% writes
|
|
collection := NewWithData(int32(b.N+50000), fmt.Sprintf("Concurrent%d", b.N), "Concurrent", 15, db)
|
|
collection.CollectionItems = []CollectionItem{
|
|
{ItemID: int32(b.N + 80000), Index: 0, Found: ItemNotFound},
|
|
}
|
|
masterList.AddCollection(collection)
|
|
default: // 90% reads
|
|
switch b.N % 5 {
|
|
case 0:
|
|
masterList.GetCollection(int32(b.N%100 + 1))
|
|
case 1:
|
|
masterList.FindCollectionsByCategory("Heritage")
|
|
case 2:
|
|
masterList.GetCollectionByName("collection 1")
|
|
case 3:
|
|
masterList.NeedsItem(1001)
|
|
case 4:
|
|
masterList.GetCompletedCollections()
|
|
}
|
|
}
|
|
}
|
|
})
|
|
} |