|
| 1 | +# Feature Flags - JsonRemedy Performance Optimization System |
| 2 | + |
| 3 | +This document explains the feature flag system used in JsonRemedy to enable progressive performance optimizations while maintaining stability and compatibility. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +JsonRemedy uses a sophisticated feature flag system to control performance optimizations at runtime. This system allows users to select the best performance profile for their use case while providing fallback options for compatibility and debugging. |
| 8 | + |
| 9 | +## Why Feature Flags for Performance? |
| 10 | + |
| 11 | +### 1. **Progressive Optimization Strategy** |
| 12 | +Instead of implementing a single optimization approach, JsonRemedy offers multiple optimization levels that can be selected based on: |
| 13 | +- **Performance requirements** - Critical vs non-critical paths |
| 14 | +- **Compatibility needs** - Legacy system support |
| 15 | +- **Debugging requirements** - Easier troubleshooting with simpler implementations |
| 16 | +- **Memory constraints** - Different memory/speed tradeoffs |
| 17 | + |
| 18 | +### 2. **Risk Mitigation** |
| 19 | +Performance optimizations often involve: |
| 20 | +- Complex algorithms that may have edge cases |
| 21 | +- Platform-specific optimizations that may not work everywhere |
| 22 | +- Memory vs speed tradeoffs that may not suit all environments |
| 23 | + |
| 24 | +Feature flags allow users to **fall back to proven implementations** if optimizations cause issues. |
| 25 | + |
| 26 | +### 3. **Benchmarking and Validation** |
| 27 | +Feature flags enable: |
| 28 | +- **A/B testing** of different optimization approaches |
| 29 | +- **Performance regression detection** by comparing implementations |
| 30 | +- **Gradual rollout** of new optimizations |
| 31 | + |
| 32 | +## Layer 3 Syntax Normalization Feature Flags |
| 33 | + |
| 34 | +### Primary Optimization Phase Selection |
| 35 | + |
| 36 | +```elixir |
| 37 | +# In config/config.exs or Application.put_env/3 |
| 38 | +config :json_remedy, :layer3_optimization_phase, 2 |
| 39 | +``` |
| 40 | + |
| 41 | +**Available Phases:** |
| 42 | + |
| 43 | +#### **Phase 0: Original Implementation** (`optimization_phase: 0`) |
| 44 | +```elixir |
| 45 | +config :json_remedy, :layer3_optimization_phase, 0 |
| 46 | +``` |
| 47 | + |
| 48 | +**When to use:** |
| 49 | +- **Debugging complex parsing issues** - Simplest implementation, easiest to understand |
| 50 | +- **Maximum compatibility** - Most conservative approach |
| 51 | +- **Legacy system support** - Proven stable implementation |
| 52 | + |
| 53 | +**Performance:** Baseline performance using string concatenation and character-by-character processing. |
| 54 | + |
| 55 | +**Trade-offs:** |
| 56 | +- ✅ Maximum stability and compatibility |
| 57 | +- ✅ Easiest to debug and understand |
| 58 | +- ❌ Slowest performance (O(n²) string operations) |
| 59 | + |
| 60 | +#### **Phase 1: IO List Optimization** (`optimization_phase: 1`) |
| 61 | +```elixir |
| 62 | +config :json_remedy, :layer3_optimization_phase, 1 |
| 63 | +``` |
| 64 | + |
| 65 | +**When to use:** |
| 66 | +- **Moderate performance improvement needed** - 2-3x faster than original |
| 67 | +- **Memory-constrained environments** - Better memory efficiency |
| 68 | +- **Large JSON processing** - Eliminates O(n²) string concatenation bottleneck |
| 69 | + |
| 70 | +**Performance:** Eliminates O(n²) string concatenation by using IO lists for O(1) append operations. |
| 71 | + |
| 72 | +**Trade-offs:** |
| 73 | +- ✅ Significant performance improvement (2-3x faster) |
| 74 | +- ✅ Better memory efficiency |
| 75 | +- ✅ Still relatively simple algorithm |
| 76 | +- ❌ More complex than original implementation |
| 77 | + |
| 78 | +#### **Phase 2: Binary Pattern Matching** (`optimization_phase: 2`) **[DEFAULT]** |
| 79 | +```elixir |
| 80 | +config :json_remedy, :layer3_optimization_phase, 2 # Default |
| 81 | +``` |
| 82 | + |
| 83 | +**When to use:** |
| 84 | +- **Maximum performance required** - 5-10x faster than original |
| 85 | +- **High-throughput JSON processing** - Eliminates String.at/2 calls |
| 86 | +- **Production environments** - Best overall performance |
| 87 | + |
| 88 | +**Performance:** Eliminates String.at/2 function calls by using binary pattern matching for maximum speed. |
| 89 | + |
| 90 | +**Trade-offs:** |
| 91 | +- ✅ Maximum performance (5-10x faster than original) |
| 92 | +- ✅ Most efficient memory usage |
| 93 | +- ✅ Leverages Erlang VM's binary optimization |
| 94 | +- ❌ Most complex implementation |
| 95 | +- ❌ Harder to debug if issues arise |
| 96 | + |
| 97 | +### Secondary IO List Optimization |
| 98 | + |
| 99 | +```elixir |
| 100 | +# Controls sub-optimization within key quoting functions |
| 101 | +config :json_remedy, :layer3_iolist_optimization, true # Default: true |
| 102 | +``` |
| 103 | + |
| 104 | +**Purpose:** Controls whether key quoting functions use IO list optimization even when not in Phase 1. |
| 105 | + |
| 106 | +**When to disable (`false`):** |
| 107 | +- **Debugging key quoting issues** - Simpler string-based implementation |
| 108 | +- **Memory debugging** - Eliminate IO list complexity |
| 109 | +- **Platform compatibility issues** - Some platforms may have IO list issues |
| 110 | + |
| 111 | +## Configuration Examples |
| 112 | + |
| 113 | +### Development Environment |
| 114 | +```elixir |
| 115 | +# config/dev.exs |
| 116 | +config :json_remedy, |
| 117 | + layer3_optimization_phase: 0, # Use original for easier debugging |
| 118 | + layer3_iolist_optimization: false |
| 119 | +``` |
| 120 | + |
| 121 | +### Testing Environment |
| 122 | +```elixir |
| 123 | +# config/test.exs |
| 124 | +config :json_remedy, |
| 125 | + layer3_optimization_phase: 2, # Test with maximum optimization |
| 126 | + layer3_iolist_optimization: true |
| 127 | +``` |
| 128 | + |
| 129 | +### Production Environment |
| 130 | +```elixir |
| 131 | +# config/prod.exs |
| 132 | +config :json_remedy, |
| 133 | + layer3_optimization_phase: 2, # Maximum performance |
| 134 | + layer3_iolist_optimization: true |
| 135 | +``` |
| 136 | + |
| 137 | +### Compatibility/Fallback Mode |
| 138 | +```elixir |
| 139 | +# For maximum compatibility when issues arise |
| 140 | +config :json_remedy, |
| 141 | + layer3_optimization_phase: 0, # Most stable implementation |
| 142 | + layer3_iolist_optimization: false |
| 143 | +``` |
| 144 | + |
| 145 | +## Runtime Configuration |
| 146 | + |
| 147 | +Feature flags can also be set at runtime: |
| 148 | + |
| 149 | +```elixir |
| 150 | +# Temporarily switch to compatibility mode |
| 151 | +Application.put_env(:json_remedy, :layer3_optimization_phase, 0) |
| 152 | + |
| 153 | +# Process some problematic JSON |
| 154 | +{:ok, result} = JsonRemedy.process(problematic_json) |
| 155 | + |
| 156 | +# Switch back to optimized mode |
| 157 | +Application.put_env(:json_remedy, :layer3_optimization_phase, 2) |
| 158 | +``` |
| 159 | + |
| 160 | +## Performance Benchmarks |
| 161 | + |
| 162 | +Based on internal testing with various JSON sizes: |
| 163 | + |
| 164 | +| Phase | Implementation | Speed vs Original | Memory Usage | Complexity | |
| 165 | +|-------|---------------|------------------|--------------|------------| |
| 166 | +| 0 | Original | 1x (baseline) | High | Low | |
| 167 | +| 1 | IO Lists | 2-3x faster | Medium | Medium | |
| 168 | +| 2 | Binary Matching | 5-10x faster | Low | High | |
| 169 | + |
| 170 | +**Test conditions:** 1MB malformed JSON with mixed syntax issues on Erlang/OTP 25+ |
| 171 | + |
| 172 | +## Troubleshooting with Feature Flags |
| 173 | + |
| 174 | +### Performance Issues |
| 175 | +1. **Start with Phase 0** to establish baseline |
| 176 | +2. **Test Phase 1** to isolate IO list optimizations |
| 177 | +3. **Enable Phase 2** only after confirming Phase 1 works |
| 178 | + |
| 179 | +### Memory Issues |
| 180 | +1. **Disable IO list optimization** first: `layer3_iolist_optimization: false` |
| 181 | +2. **Use Phase 0** if memory issues persist |
| 182 | +3. **Monitor memory usage** with `:observer.start()` |
| 183 | + |
| 184 | +### Parsing Errors |
| 185 | +1. **Switch to Phase 0** to eliminate optimization-related issues |
| 186 | +2. **Compare results** between phases to isolate the problem |
| 187 | +3. **Report issues** with specific phase and configuration details |
| 188 | + |
| 189 | +## Implementation Architecture |
| 190 | + |
| 191 | +The feature flag system preserves the **single-pass optimization principle** that prevents catastrophic performance regressions: |
| 192 | + |
| 193 | +```elixir |
| 194 | +# In JsonRemedy.Layer3.SyntaxNormalization |
| 195 | +defp normalize_syntax(content) do |
| 196 | + case Application.get_env(:json_remedy, :layer3_optimization_phase, 2) do |
| 197 | + 2 -> normalize_syntax_binary_optimized(content) # Binary optimization |
| 198 | + 1 -> normalize_syntax_iolist(content) # IO list optimization |
| 199 | + _ -> normalize_syntax_original(content) # Original implementation |
| 200 | + end |
| 201 | +end |
| 202 | +``` |
| 203 | + |
| 204 | +**Key principle:** All phases maintain **integrated single-pass processing**. The feature flags select between different **implementations** of the same algorithm, not between single-pass vs multi-pass approaches. |
| 205 | + |
| 206 | +## Best Practices |
| 207 | + |
| 208 | +### 1. **Development Workflow** |
| 209 | +- **Start with Phase 0** during development for easier debugging |
| 210 | +- **Test with Phase 2** before deployment to catch optimization-specific issues |
| 211 | +- **Use Phase 1** as middle ground when Phase 2 causes issues |
| 212 | + |
| 213 | +### 2. **Production Deployment** |
| 214 | +- **Always benchmark** your specific JSON patterns with different phases |
| 215 | +- **Monitor performance** after enabling optimizations |
| 216 | +- **Have fallback plan** ready if issues arise |
| 217 | + |
| 218 | +### 3. **Debugging Strategy** |
| 219 | +- **Use Phase 0** to isolate parsing logic issues from optimization issues |
| 220 | +- **Compare outputs** between phases to verify correctness |
| 221 | +- **Enable optimizations incrementally** (0 → 1 → 2) |
| 222 | + |
| 223 | +### 4. **Performance Testing** |
| 224 | +- **Benchmark with realistic data** - your actual JSON patterns |
| 225 | +- **Test with various sizes** - optimizations may have different curves |
| 226 | +- **Monitor memory usage** - especially with large JSON files |
| 227 | + |
| 228 | +## Future Extensibility |
| 229 | + |
| 230 | +The feature flag system is designed for extensibility: |
| 231 | + |
| 232 | +```elixir |
| 233 | +# Future: Phase 3 could add SIMD optimizations |
| 234 | +config :json_remedy, :layer3_optimization_phase, 3 |
| 235 | + |
| 236 | +# Future: Platform-specific optimizations |
| 237 | +config :json_remedy, :layer3_platform_optimization, :native_code |
| 238 | + |
| 239 | +# Future: Memory vs speed profiles |
| 240 | +config :json_remedy, :layer3_performance_profile, :memory_optimized |
| 241 | +``` |
| 242 | + |
| 243 | +This architecture allows JsonRemedy to evolve its performance optimizations while maintaining backward compatibility and providing users with fine-grained control over performance characteristics. |
0 commit comments