-
Notifications
You must be signed in to change notification settings - Fork 46
Description
Description
Performance analysis reveals that frontmatter["on"] is accessed 34 times across workflow compiler files during each compilation. Caching this value on first access could eliminate 33 redundant map lookups, providing a low-effort performance improvement.
Current State
High-frequency access pattern:
frontmatter["on"]accessed 34 times per workflow compilation- Only 1 initial access needed, remaining 33 are redundant lookups
- Pattern repeated across multiple compiler files
Access frequency by field (from schema analysis):
34× frontmatter["on"] ← HIGHEST FREQUENCY
3× frontmatter["safe-outputs"]
3× frontmatter["github-token"]
2× frontmatter["safe-inputs"]
2× frontmatter["permissions"]
1× (16 other fields)
Files with highest access (top 5):
schedule_preprocessing_test.go- 11 accessesschedule_preprocessing.go- 5 accesseslabel_trigger_integration_test.go- 5 accessesstop_after.go- 3 accessesfilters.go- 3 accesses
Impact
Performance:
- Map lookups have O(1) average complexity but still involve hashing and key comparison
- 33 redundant lookups × thousands of compilations = unnecessary overhead
- Quick win with minimal code changes
Code Quality:
- Reduces repetitive code patterns
- Makes intent clearer (cache indicates "used frequently")
- Sets precedent for caching other high-frequency fields
Suggested Changes
Option 1: Compiler Struct Field (Recommended)
Add cached field to compiler struct:
// In pkg/workflow/compiler.go or relevant compiler struct
type Compiler struct {
frontmatter map[string]any
// Cached high-frequency fields
cachedOnField any // Cached from frontmatter["on"]
// ... other fields
}
// Add getter method
func (c *Compiler) GetOnField() any {
if c.cachedOnField == nil {
c.cachedOnField = c.frontmatter["on"]
}
return c.cachedOnField
}Replace all 34 accesses:
// BEFORE
onField := frontmatter["on"]
// AFTER
onField := compiler.GetOnField()Option 2: Local Variable in High-Access Functions
For functions that access on multiple times:
// In schedule_preprocessing.go
func preprocessSchedule(frontmatter map[string]any) error {
// Cache at function start
onField := frontmatter["on"]
// Use cached value in all 5 locations
if onField == nil { ... }
schedule := extractSchedule(onField)
// ... 3 more uses
}Option 3: Lazy Evaluation Pattern
type CachedFrontmatter struct {
data map[string]any
onFieldCache *any // nil = not yet cached
}
func (cf *CachedFrontmatter) On() any {
if cf.onFieldCache == nil {
value := cf.data["on"]
cf.onFieldCache = &value
}
return *cf.onFieldCache
}Files Affected
Primary files (11+ accesses each):
pkg/workflow/schedule_preprocessing_test.go(11 accesses)pkg/workflow/schedule_preprocessing.go(5 accesses)pkg/workflow/label_trigger_integration_test.go(5 accesses)
Secondary files (3-4 accesses each):
pkg/workflow/stop_after.gopkg/workflow/filters.go- Others with 1-2 accesses
Total: Estimated 10-15 files to update
Success Criteria
- ✅
frontmatter["on"]accessed only once per compilation (cached afterward) - ✅ All 34 original access points now use cached value
- ✅ No functionality changes (behavior identical)
- ✅ All tests pass (no regressions)
- ✅ Performance benchmarks show measurable improvement (even if small)
Testing
Validation approach:
- Add debug logging to cache getter to verify single access
- Run existing test suite to ensure no behavior changes
- Optional: Add benchmark comparing before/after performance
// Benchmark test
func BenchmarkCompilationWithCache(b *testing.B) {
for i := 0; i < b.N; i++ {
compiler.Compile("test-workflow.md")
}
}Source
Extracted from Schema Validation Complexity & Performance Analysis discussion #11802
Relevant excerpt:
High-Frequency Access - Caching Opportunity:
frontmatter["on"]accessed 34 times across workflow compiler files- Opportunity to cache this value on first access
- Could eliminate 33 redundant map lookups per compilation
Priority
Medium - Low-effort performance improvement. Not critical but provides measurable benefit with minimal risk.
Implementation Estimate
Effort: 1 day (quick win)
- 2-3 hours: Implement caching mechanism (Option 1 recommended)
- 2-3 hours: Update all 34 access points to use cached value
- 1-2 hours: Test and verify no regressions
Risk: Very low - purely an internal optimization with no external API changes
AI generated by Discussion Task Miner - Code Quality Improvement Agent
- expires on Feb 9, 2026, 9:07 PM UTC