-
Notifications
You must be signed in to change notification settings - Fork 77
Description
GitHub Issue: Performance: Eliminate transaction name string operations in hot path
Problem
The current implementation performs unnecessary string operations for transaction names in the hot path, causing memory allocations and CPU overhead on every transaction invocation.
Current Implementation Issues
1. String Cloning in GooseUser
pub struct GooseUser {
// String fields that get cloned repeatedly
pub transaction_name: String,
pub scenario_name: String,
// ...
}2. Repeated String Operations
In invoke_transaction_function():
- Transaction names are cloned multiple times per invocation
- String comparisons for transaction lookups
- Unnecessary string allocations for logging/metrics
Performance Impact
- Memory allocations: 100% elimination potential for transaction name allocations
- CPU overhead: String cloning and comparison operations
- GC pressure: Frequent allocation/deallocation of transaction name strings
- Scale impact: Grows linearly with transaction execution rate
Proposed Solution
Option 1: Simple Integer Indices (Recommended - Low Complexity)
Replace string fields with simple integer indices that reference existing data structures:
pub struct GooseUser {
// Replace String with lightweight indices into existing collections
pub current_scenario_index: usize, // Index into scenarios Vec
pub current_transaction_index: usize, // Index into transactions Vec
// Remove transaction_name and scenario_name fields entirely
}
// Transaction names are already stored in the GooseAttack structure:
impl GooseUser {
fn get_current_transaction_name(&self, goose_attack: &GooseAttack) -> &str {
// Direct reference to existing string - no allocation
&goose_attack.scenarios[self.current_scenario_index]
.transactions[self.current_transaction_index].name
}
}Option 2: Cow (Clone-on-Write) Strings
Use Cow<'static, str> to avoid cloning when possible:
use std::borrow::Cow;
pub struct GooseUser {
pub transaction_name: Cow<'static, str>, // Only clones when necessary
pub scenario_name: Cow<'static, str>,
// ...
}Option 3: Arc for Shared Ownership (Medium Complexity)
Use Arc<str> for cheap cloning of immutable strings:
use std::sync::Arc;
pub struct GooseUser {
pub transaction_name: Arc<str>, // Cheap to clone, shared ownership
pub scenario_name: Arc<str>,
// ...
}Recommended Approach: Simple Integer Indices
Why this is better than string interning:
- No external dependencies - uses existing data structures
- Zero complexity overhead - simple array indexing
- Leverages existing architecture - GooseAttack already stores all names
- Same performance benefits - eliminates string allocations
- Easier to maintain - straightforward implementation
Implementation Approach
Phase 1: Structure Simplification
- Remove String fields from GooseUser
- Add index fields that reference existing collections
- Update constructor to use indices instead of strings
Phase 2: Hot Path Optimization
- Update
invoke_transaction_function()to use integer operations - Pass indices instead of cloning strings
- Only resolve strings when actually needed for logging
Phase 3: Helper Methods
- Add getter methods that return
&strreferences to existing data - Update logging/reporting code to use getter methods
- Ensure all string access goes through the existing collections
Expected Performance Gains
- Memory reduction: 100% elimination of transaction name string allocations
- CPU improvement: Faster integer comparisons vs string operations
- Cache efficiency: Better memory locality with integer indices
- Simplicity: No external dependencies or complex data structures
- Maintainability: Uses existing GooseAttack architecture
Testing Strategy
- Unit tests: Verify index-based lookups work correctly
- Integration tests: Ensure transaction execution remains correct
- Performance tests: Measure allocation reduction and CPU improvement
- Memory profiling: Validate elimination of string allocations
Acceptance Criteria
- GooseUser uses string indices instead of String fields
- Transaction name operations use integer comparisons
- 100% elimination of transaction name string allocations in hot path
- All existing functionality preserved
- Performance benchmarks show measurable improvement
- Memory usage reduced for high-transaction-rate tests
Related Issues
Part of comprehensive performance optimization effort. Related to:
- Performance: Eliminate string formatting in metrics aggregation hot path #637 (Metrics key optimization)
- Performance: Eliminate string allocations in request metrics hot path #638 (String allocation reduction)
- Performance: Eliminate unnecessary header processing in request hot path #639 (Header processing optimization)
Additional Notes
This optimization complements the string allocation reductions in #638 by addressing a different category of string operations. Together, they should significantly reduce memory pressure in high-throughput scenarios.
Labels
- enhancement
Priority
Priority 2 (High Impact)