-
Notifications
You must be signed in to change notification settings - Fork 107
Open
Description
Complex games can have thousands of formula evaluations per frame. Currently, there's no way to identify performance bottlenecks in formula calculations. Developers need profiling tools to optimize their game balance formulas.
Use Cases
- Identify slow formulas: Find which formulas take the most time to evaluate
- Cache hit analysis: Understand cache efficiency for repeated calculations
- Hotspot detection: Locate expressions that run too frequently
- Memory tracking: Monitor formula-related memory allocation
- Comparison benchmarks: Compare formula implementations
Proposed API
Profiler Class
// src/utils/Profiler.ts
export interface ProfileResult {
formulaId: string
executionCount: number
totalTimeMs: number
averageTimeMs: number
minTimeMs: number
maxTimeMs: number
cacheHits: number
cacheMisses: number
}
export interface ProfileSession {
id: string
startTime: Date
endTime?: Date
results: Map<string, ProfileResult>
}
export class Profiler {
static startSession(name?: string): ProfileSession
static endSession(session: ProfileSession): ProfileReport
static getActiveSession(): ProfileSession | null
static profile<T>(name: string, fn: () => T): T
static profileAsync<T>(name: string, fn: () => Promise<T>): Promise<T>
static mark(name: string): void
static measure(name: string, startMark: string, endMark?: string): number
}Integration with fx singleton
// Profile a specific formula
const damage = fx.profileEvaluate('damage-calc', 'ATK * (1 - DEF/100)')
// Start profiling session
fx.startProfiling()
// ... game loop with formula evaluations ...
const report = fx.stopProfiling()
// Get formula statistics
const stats = fx.getFormulaStats('damage-calc')
console.log(`Average: ${stats.averageTimeMs}ms, Calls: ${stats.executionCount}`)Profile Report Format
interface ProfileReport {
sessionDuration: number
totalEvaluations: number
totalTimeMs: number
// Sorted by total time (desc)
slowestFormulas: ProfileResult[]
// Sorted by call count (desc)
mostFrequent: ProfileResult[]
// Formulas with poor cache utilization
cacheMissers: ProfileResult[]
// Export formats
toJSON(): string
toCSV(): string
toMarkdown(): string
}Example Output
# Formula Performance Report
Session: combat-loop-analysis
Duration: 5000ms | Total Evaluations: 15,234
## Slowest Formulas
| Formula | Calls | Total (ms) | Avg (ms) | Cache Hit % |
|---------|-------|------------|----------|-------------|
| enemy-ai-decision | 1,200 | 450 | 0.375 | 12% |
| damage-calc | 8,500 | 320 | 0.038 | 89% |
| crit-chance | 4,000 | 85 | 0.021 | 95% |
## Recommendations
- `enemy-ai-decision`: Low cache hit rate. Consider memoization.
- `damage-calc`: High call volume. Review call sites for redundancy.Implementation Details
Minimal Overhead Mode
// Profiling disabled in production (zero overhead)
if (process.env.NODE_ENV === 'production') {
Profiler.disable()
}
// Selective profiling
Profiler.enable({
formulas: ['damage-calc', 'heal-calc'],
threshold: 1 // Only track if > 1ms
})Memory Profiling (Optional)
// Track allocations during formula evaluation
fx.profileMemory('complex-formula', () => {
return fx.evaluate(complexExpression)
})
// Returns: { result, allocations: 1240, peakMemory: '2.4KB' }Visual Integration
The profiler should integrate with the visual editor to:
- Highlight slow formulas in red
- Show execution counts on formula nodes
- Provide real-time performance overlay
Metadata
Metadata
Assignees
Labels
No labels