package renderer import ( "fmt" "testing" "github.com/ungluedlabs/go-jdenticon/internal/engine" ) // Benchmark optimized PNG renderer vs original FastPNG renderer func BenchmarkOptimizedPNGToPNG(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { size := benchmarkSizes[i%len(benchmarkSizes)] renderer := NewPNGRenderer(size) // Add some shapes renderer.SetBackground("#f0f0f0", 1.0) for j := 0; j < 3; j++ { color := benchmarkColors[j%len(benchmarkColors)] points := benchmarkPoints[j%len(benchmarkPoints)] renderer.BeginShape(color) renderer.AddPolygon(points) renderer.EndShape() } _, err := renderer.ToPNG() if err != nil { b.Fatalf("ToPNG failed: %v", err) } } } // Benchmark PNG memory usage with different allocation patterns func BenchmarkPNGMemoryPatterns(b *testing.B) { // Shared test data testShapes := []struct { color string points []engine.Point }{ {"#ff0000", benchmarkPoints[0]}, {"#00ff00", benchmarkPoints[1]}, {"#0000ff", benchmarkPoints[2]}, } b.Run("OptimizedPNG", func(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { renderer := NewPNGRenderer(256) renderer.SetBackground("#ffffff", 1.0) for _, shape := range testShapes { renderer.BeginShape(shape.color) renderer.AddPolygon(shape.points) renderer.EndShape() } _, err := renderer.ToPNG() if err != nil { b.Fatalf("ToPNG failed: %v", err) } } }) b.Run("PNGWrapper", func(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { renderer := NewPNGRenderer(256) renderer.SetBackground("#ffffff", 1.0) for _, shape := range testShapes { renderer.BeginShape(shape.color) renderer.AddPolygon(shape.points) renderer.EndShape() } _, err := renderer.ToPNG() if err != nil { b.Fatalf("ToPNG failed: %v", err) } } }) } // Benchmark different icon sizes to see memory scaling func BenchmarkOptimizedPNGSizes(b *testing.B) { testShapes := []struct { color string points []engine.Point }{ {"#ff0000", benchmarkPoints[0]}, {"#00ff00", benchmarkPoints[1]}, {"#0000ff", benchmarkPoints[2]}, } sizes := []int{64, 128, 256, 512} for _, size := range sizes { b.Run(fmt.Sprintf("Size%d", size), func(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { renderer := NewPNGRenderer(size) renderer.SetBackground("#ffffff", 1.0) for _, shape := range testShapes { renderer.BeginShape(shape.color) renderer.AddPolygon(shape.points) renderer.EndShape() } _, err := renderer.ToPNG() if err != nil { b.Fatalf("ToPNG failed: %v", err) } } }) } } // Benchmark complex shape rendering with optimized renderer func BenchmarkOptimizedComplexPNGRendering(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { renderer := NewPNGRenderer(256) renderer.SetBackground("#f8f8f8", 1.0) // Render many shapes to simulate complex icon for j := 0; j < 12; j++ { color := benchmarkColors[j%len(benchmarkColors)] points := benchmarkPoints[j%len(benchmarkPoints)] renderer.BeginShape(color) renderer.AddPolygon(points) renderer.EndShape() } _, err := renderer.ToPNG() if err != nil { b.Fatalf("ToPNG failed: %v", err) } } } // Benchmark pooling efficiency func BenchmarkPoolingEfficiency(b *testing.B) { b.Run("WithPooling", func(b *testing.B) { b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { renderer := NewPNGRenderer(128) renderer.SetBackground("#ffffff", 1.0) // Add multiple polygons to exercise pooling for j := 0; j < 10; j++ { renderer.BeginShape("#808080") renderer.AddPolygon(benchmarkPoints[j%len(benchmarkPoints)]) renderer.EndShape() } _, err := renderer.ToPNG() if err != nil { b.Fatalf("ToPNG failed: %v", err) } } }) }