mirror of
https://github.com/semihalev/twig.git
synced 2026-03-14 13:55:46 +01:00
- Implemented pooled slices for function arguments - Added specialized pooling for variable node and literal node objects - Modified array and hash node evaluation to reduce allocations - Optimized test and filter evaluation with pooled resources - Added comprehensive benchmarks to validate improvements - Updated node pool implementation to remove duplicate declarations - Fixed memory allocations in merge filter to correctly handle array manipulations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
129 lines
No EOL
3.1 KiB
Go
129 lines
No EOL
3.1 KiB
Go
package twig
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func BenchmarkRenderContextCreation(b *testing.B) {
|
|
engine := New()
|
|
|
|
// Create a simple context with a few variables
|
|
contextVars := map[string]interface{}{
|
|
"user": map[string]interface{}{
|
|
"name": "John Doe",
|
|
"email": "john@example.com",
|
|
"age": 30,
|
|
},
|
|
"items": []string{"item1", "item2", "item3"},
|
|
"count": 42,
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
ctx := NewRenderContext(engine.environment, contextVars, engine)
|
|
ctx.Release() // Return to pool after use
|
|
}
|
|
}
|
|
|
|
func BenchmarkRenderContextCloning(b *testing.B) {
|
|
engine := New()
|
|
|
|
// Create a parent context with some variables, blocks, and macros
|
|
parentContext := map[string]interface{}{
|
|
"user": map[string]interface{}{
|
|
"name": "John Doe",
|
|
"email": "john@example.com",
|
|
},
|
|
"items": []string{"item1", "item2", "item3"},
|
|
}
|
|
|
|
// Create the parent context
|
|
parent := NewRenderContext(engine.environment, parentContext, engine)
|
|
|
|
// Add some blocks
|
|
header := &TextNode{content: "Header Content", line: 1}
|
|
footer := &TextNode{content: "Footer Content", line: 2}
|
|
parent.blocks["header"] = []Node{header}
|
|
parent.blocks["footer"] = []Node{footer}
|
|
|
|
// Add a simple macro
|
|
macroNode := &MacroNode{
|
|
name: "format",
|
|
line: 3,
|
|
}
|
|
parent.macros["format"] = macroNode
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// Clone the context - this should reuse memory from pools
|
|
child := parent.Clone()
|
|
|
|
// Do some operations on the child context
|
|
child.SetVariable("newVar", "test value")
|
|
|
|
// Release the child context
|
|
child.Release()
|
|
}
|
|
|
|
// Clean up parent context
|
|
parent.Release()
|
|
}
|
|
|
|
func BenchmarkNestedContextCreation(b *testing.B) {
|
|
engine := New()
|
|
baseContext := map[string]interface{}{"base": "value"}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// Create a chain of 5 nested contexts
|
|
ctx1 := NewRenderContext(engine.environment, baseContext, engine)
|
|
ctx2 := ctx1.Clone()
|
|
ctx3 := ctx2.Clone()
|
|
ctx4 := ctx3.Clone()
|
|
ctx5 := ctx4.Clone()
|
|
|
|
// Make some changes to test variable lookup
|
|
ctx5.SetVariable("level5", "value5")
|
|
ctx3.SetVariable("level3", "value3")
|
|
|
|
// Release in reverse order
|
|
ctx5.Release()
|
|
ctx4.Release()
|
|
ctx3.Release()
|
|
ctx2.Release()
|
|
ctx1.Release()
|
|
}
|
|
}
|
|
|
|
func BenchmarkContextVariableLookup(b *testing.B) {
|
|
engine := New()
|
|
|
|
// Create a chain of contexts with variables at different levels
|
|
rootCtx := NewRenderContext(engine.environment, map[string]interface{}{
|
|
"rootVar": "root value",
|
|
"shared": "root version",
|
|
}, engine)
|
|
|
|
level1 := rootCtx.Clone()
|
|
level1.SetVariable("level1Var", "level1 value")
|
|
level1.SetVariable("shared", "level1 version")
|
|
|
|
level2 := level1.Clone()
|
|
level2.SetVariable("level2Var", "level2 value")
|
|
|
|
// Setup complete, start benchmark
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// Test variable lookup at different levels
|
|
level2.GetVariable("level2Var") // Local var
|
|
level2.GetVariable("level1Var") // Parent var
|
|
level2.GetVariable("rootVar") // Root var
|
|
level2.GetVariable("shared") // Shadowed var
|
|
level2.GetVariable("nonExistentVar") // Missing var
|
|
}
|
|
|
|
// Clean up
|
|
level2.Release()
|
|
level1.Release()
|
|
rootCtx.Release()
|
|
} |