tint_me 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +17 -0
 - data/README.md +104 -25
 - data/lib/tint_me/sgr_builder.rb +1 -1
 - data/lib/tint_me/style/types.rb +21 -0
 - data/lib/tint_me/style.rb +69 -0
 - data/lib/tint_me/version.rb +1 -1
 - data/sig/dry-schema.rbs +8 -0
 - data/sig/dry-types.rbs +11 -0
 - data/sig/tint_me/error.rbs +4 -0
 - data/sig/tint_me/sgr_builder.rbs +60 -0
 - data/sig/tint_me/style/schema.rbs +5 -0
 - data/sig/tint_me/style/types.rbs +14 -0
 - data/sig/tint_me/style.rbs +73 -0
 - data/sig/tint_me.rbs +1 -45
 - metadata +13 -31
 - data/.rubocop_todo.yml +0 -7
 - data/.serena/project.yml +0 -68
 - data/.simplecov +0 -24
 - data/.yardopts +0 -6
 - data/AGENTS.md +0 -60
 - data/CLAUDE.md +0 -1
 - data/RELEASING.md +0 -202
 - data/Rakefile +0 -18
 - data/benchmark/2025-09-08-style-caching-optimization/01_baseline_results.txt +0 -39
 - data/benchmark/2025-09-08-style-caching-optimization/02_with_full_caching_results.txt +0 -54
 - data/benchmark/2025-09-08-style-caching-optimization/03_prefix_only_caching_results.txt +0 -107
 - data/benchmark/2025-09-08-style-caching-optimization/04_baseline_vs_optimized_analysis.txt +0 -65
 - data/benchmark/2025-09-08-style-caching-optimization/05_caching_approaches_comparison.txt +0 -59
 - data/benchmark/2025-09-08-style-caching-optimization/06_append_operator_results.txt +0 -107
 - data/benchmark/2025-09-08-style-caching-optimization/07_string_concatenation_comparison.txt +0 -66
 - data/benchmark/2025-09-08-style-caching-optimization/08_with_freeze_optimization_results.txt +0 -107
 - data/benchmark/2025-09-08-style-caching-optimization/09_freeze_optimization_analysis.txt +0 -49
 - data/benchmark/2025-09-08-style-caching-optimization/10_constant_access_results.txt +0 -107
 - data/benchmark/2025-09-08-style-caching-optimization/11_constant_vs_cache_analysis.txt +0 -74
 - data/benchmark/2025-09-08-style-caching-optimization/12_empty_prefix_analysis.txt +0 -81
 - data/benchmark/2025-09-08-style-caching-optimization/13_nil_check_optimization_results.txt +0 -107
 - data/benchmark/2025-09-08-style-caching-optimization/14_nil_vs_empty_check_analysis.txt +0 -81
 - data/benchmark/2025-09-08-style-caching-optimization/README.md +0 -45
 - data/benchmark/2025-09-08-style-caching-optimization/benchmark_script.rb +0 -180
 - data/docs/agents/git-pr.md +0 -298
 - data/docs/agents/languages.md +0 -388
 - data/docs/agents/rubocop.md +0 -55
 - data/mise.toml +0 -5
 
| 
         @@ -1,74 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            CONSTANT ACCESS vs CACHING ANALYSIS
         
     | 
| 
       2 
     | 
    
         
            -
            ====================================
         
     | 
| 
       3 
     | 
    
         
            -
            Date: 2025-09-08
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            ## Implementation Comparison
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            ### Caching Approach (Previous)
         
     | 
| 
       8 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       9 
     | 
    
         
            -
            # Initialization
         
     | 
| 
       10 
     | 
    
         
            -
            @reset_code = sgr_builder.reset_code
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            # Usage
         
     | 
| 
       13 
     | 
    
         
            -
            "#{@prefix}#{text}#{@reset_code}"
         
     | 
| 
       14 
     | 
    
         
            -
            ```
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            ### Constant Access Approach (Current)
         
     | 
| 
       17 
     | 
    
         
            -
            ```ruby  
         
     | 
| 
       18 
     | 
    
         
            -
            # Initialization
         
     | 
| 
       19 
     | 
    
         
            -
            # (no @reset_code caching)
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            # Usage  
         
     | 
| 
       22 
     | 
    
         
            -
            "#{@prefix}#{text}#{SGRBuilder::RESET_CODE}"
         
     | 
| 
       23 
     | 
    
         
            -
            ```
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            ## Performance & Memory Results
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
            | Metric | Caching | Constant Access | Difference |
         
     | 
| 
       28 
     | 
    
         
            -
            |--------|---------|-----------------|------------|
         
     | 
| 
       29 
     | 
    
         
            -
            | **Performance** | 5.44M/s | 5.38M/s | **1% slower** |
         
     | 
| 
       30 
     | 
    
         
            -
            | **Creation Memory** | 6.1KB | 6.0KB | **8 bytes saved** |
         
     | 
| 
       31 
     | 
    
         
            -
            | **Runtime Memory** | 424 bytes | 616 bytes | **45% more** |
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            ## Analysis
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            ### Memory Trade-offs:
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
            **Creation Time:**
         
     | 
| 
       38 
     | 
    
         
            -
            - ✅ **8 bytes saved per Style instance** (no @reset_code storage)
         
     | 
| 
       39 
     | 
    
         
            -
            - Negligible but consistent savings
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            **Runtime:**
         
     | 
| 
       42 
     | 
    
         
            -
            - ❌ **45% more memory per call** for simple styles (424 → 616 bytes)
         
     | 
| 
       43 
     | 
    
         
            -
            - Suggests constant lookup has slight overhead
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
            ### Performance Impact:
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
            - **1% slower performance** - minimal but measurable
         
     | 
| 
       48 
     | 
    
         
            -
            - Constant lookup vs instance variable access overhead
         
     | 
| 
       49 
     | 
    
         
            -
            - Still much faster than baseline (5.38M vs 766k original)
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
            ### Code Complexity:
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            **Constant Access Pros:**
         
     | 
| 
       54 
     | 
    
         
            -
            - Slightly less memory per instance  
         
     | 
| 
       55 
     | 
    
         
            -
            - Fewer instance variables
         
     | 
| 
       56 
     | 
    
         
            -
            - Direct reference to source of truth
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
            **Caching Pros:**  
         
     | 
| 
       59 
     | 
    
         
            -
            - Faster runtime performance
         
     | 
| 
       60 
     | 
    
         
            -
            - Lower runtime memory usage
         
     | 
| 
       61 
     | 
    
         
            -
            - Simpler call method (no constant lookup)
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
            ## Recommendation
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
            **Keep the caching approach** for optimal performance:
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            1. **Performance priority**: The 1% performance difference matters for a performance-critical method
         
     | 
| 
       68 
     | 
    
         
            -
            2. **Runtime efficiency**: Lower memory usage during frequent calls
         
     | 
| 
       69 
     | 
    
         
            -
            3. **Minimal memory cost**: 8 bytes per instance is negligible for the benefits
         
     | 
| 
       70 
     | 
    
         
            -
            4. **Consistent pattern**: Matches the prefix caching strategy
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
            The reset_code is accessed on every Style#call, making instance variable access more efficient than constant lookup. The tiny memory savings don't justify the performance cost.
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
            **Final implementation: Cache both @prefix and @reset_code**
         
     | 
| 
         @@ -1,81 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            EMPTY PREFIX ANALYSIS
         
     | 
| 
       2 
     | 
    
         
            -
            =====================
         
     | 
| 
       3 
     | 
    
         
            -
            Date: 2025-09-08
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            ## When @prefix is Empty
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            Based on testing, `@prefix` becomes empty ("") in these cases:
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            1. **No styling attributes**: `Style.new`
         
     | 
| 
       10 
     | 
    
         
            -
            2. **Nil values**: `Style.new(foreground: nil)`
         
     | 
| 
       11 
     | 
    
         
            -
            3. **Default values**: `Style.new(foreground: :default)`
         
     | 
| 
       12 
     | 
    
         
            -
            4. **False effects**: `Style.new(bold: false)`
         
     | 
| 
       13 
     | 
    
         
            -
            5. **Default instance**: `Style.new.to_h` result
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            **Key Finding**: `@prefix` is NEVER nil, always either `""` (empty) or a non-empty string.
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
            ## Usage Likelihood Analysis
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            ### High Probability Cases:
         
     | 
| 
       20 
     | 
    
         
            -
            - **Default/plain text styling**: Applications may use `Style.new` for conditional styling
         
     | 
| 
       21 
     | 
    
         
            -
            - **Template systems**: May create base styles that are sometimes empty
         
     | 
| 
       22 
     | 
    
         
            -
            - **Configuration-driven styling**: User settings might result in "no styling"
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            ### Low Probability Cases:
         
     | 
| 
       25 
     | 
    
         
            -
            - **Performance-critical code**: Unlikely to create empty styles intentionally
         
     | 
| 
       26 
     | 
    
         
            -
            - **Library internal usage**: Most internal usage probably has specific styling
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            ## Current vs Alternative Implementations
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            ### Current: `empty?` check
         
     | 
| 
       31 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       32 
     | 
    
         
            -
            def call(text)
         
     | 
| 
       33 
     | 
    
         
            -
              return text if @prefix.empty?
         
     | 
| 
       34 
     | 
    
         
            -
              "#{@prefix}#{text}#{@reset_code}"
         
     | 
| 
       35 
     | 
    
         
            -
            end
         
     | 
| 
       36 
     | 
    
         
            -
            ```
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
            ### Alternative 1: Length check
         
     | 
| 
       39 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       40 
     | 
    
         
            -
            def call(text)
         
     | 
| 
       41 
     | 
    
         
            -
              return text if @prefix.length == 0
         
     | 
| 
       42 
     | 
    
         
            -
              "#{@prefix}#{text}#{@reset_code}"
         
     | 
| 
       43 
     | 
    
         
            -
            end
         
     | 
| 
       44 
     | 
    
         
            -
            ```
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
            ### Alternative 2: String comparison
         
     | 
| 
       47 
     | 
    
         
            -
            ```ruby  
         
     | 
| 
       48 
     | 
    
         
            -
            def call(text)
         
     | 
| 
       49 
     | 
    
         
            -
              return text if @prefix == ""
         
     | 
| 
       50 
     | 
    
         
            -
              "#{@prefix}#{text}#{@reset_code}"
         
     | 
| 
       51 
     | 
    
         
            -
            end
         
     | 
| 
       52 
     | 
    
         
            -
            ```
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
            ### Alternative 3: No check (always interpolate)
         
     | 
| 
       55 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       56 
     | 
    
         
            -
            def call(text)
         
     | 
| 
       57 
     | 
    
         
            -
              "#{@prefix}#{text}#{@reset_code}"
         
     | 
| 
       58 
     | 
    
         
            -
            end
         
     | 
| 
       59 
     | 
    
         
            -
            ```
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
            ## Performance Considerations
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
            **If empty styles are rare (<5% of calls):**
         
     | 
| 
       64 
     | 
    
         
            -
            - Current `empty?` check may be unnecessary overhead
         
     | 
| 
       65 
     | 
    
         
            -
            - Alternative 3 (no check) might be faster overall
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            **If empty styles are common (>20% of calls):**
         
     | 
| 
       68 
     | 
    
         
            -
            - Current implementation is optimal
         
     | 
| 
       69 
     | 
    
         
            -
            - Early return saves string interpolation cost
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
            ## Recommendation for Testing
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
            Test Alternative 3 (no empty check) to see if:
         
     | 
| 
       74 
     | 
    
         
            -
            1. The empty check overhead exceeds the interpolation savings
         
     | 
| 
       75 
     | 
    
         
            -
            2. Performance improves when most styles are non-empty
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
            This would be especially valuable since empty styles might be rare in typical usage patterns.
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
            ## Conclusion
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            The `nil?` vs `empty?` question is moot since `@prefix` is never nil. The real question is whether the `empty?` check itself is worth the overhead for the expected usage patterns of the library.
         
     | 
| 
         @@ -1,107 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            ============================================================
         
     | 
| 
       2 
     | 
    
         
            -
            TIntMe Style Performance Benchmark
         
     | 
| 
       3 
     | 
    
         
            -
            ============================================================
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            Memory Usage Analysis:
         
     | 
| 
       6 
     | 
    
         
            -
            ----------------------------------------
         
     | 
| 
       7 
     | 
    
         
            -
            Calculating -------------------------------------
         
     | 
| 
       8 
     | 
    
         
            -
             Create simple style     6.056k memsize (     0.000  retained)
         
     | 
| 
       9 
     | 
    
         
            -
                                    58.000  objects (     0.000  retained)
         
     | 
| 
       10 
     | 
    
         
            -
                                     2.000  strings (     0.000  retained)
         
     | 
| 
       11 
     | 
    
         
            -
            Create complex style     7.752k memsize (     0.000  retained)
         
     | 
| 
       12 
     | 
    
         
            -
                                    79.000  objects (     0.000  retained)
         
     | 
| 
       13 
     | 
    
         
            -
                                     9.000  strings (     0.000  retained)
         
     | 
| 
       14 
     | 
    
         
            -
            Apply simple style (short text)
         
     | 
| 
       15 
     | 
    
         
            -
                                   424.000  memsize (     0.000  retained)
         
     | 
| 
       16 
     | 
    
         
            -
                                     3.000  objects (     0.000  retained)
         
     | 
| 
       17 
     | 
    
         
            -
                                     1.000  strings (     0.000  retained)
         
     | 
| 
       18 
     | 
    
         
            -
            Apply complex style (short text)
         
     | 
| 
       19 
     | 
    
         
            -
                                   264.000  memsize (     0.000  retained)
         
     | 
| 
       20 
     | 
    
         
            -
                                     2.000  objects (     0.000  retained)
         
     | 
| 
       21 
     | 
    
         
            -
                                     1.000  strings (     0.000  retained)
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            Comparison:
         
     | 
| 
       24 
     | 
    
         
            -
            Apply complex style (short text):        264 allocated
         
     | 
| 
       25 
     | 
    
         
            -
            Apply simple style (short text):        424 allocated - 1.61x more
         
     | 
| 
       26 
     | 
    
         
            -
             Create simple style:       6056 allocated - 22.94x more
         
     | 
| 
       27 
     | 
    
         
            -
            Create complex style:       7752 allocated - 29.36x more
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            Performance Benchmark (operations per second):
         
     | 
| 
       30 
     | 
    
         
            -
            ----------------------------------------
         
     | 
| 
       31 
     | 
    
         
            -
            ruby 3.2.9 (2025-07-24 revision 8f611e0c46) [arm64-darwin24]
         
     | 
| 
       32 
     | 
    
         
            -
            Warming up --------------------------------------
         
     | 
| 
       33 
     | 
    
         
            -
             Create simple style     2.856k i/100ms
         
     | 
| 
       34 
     | 
    
         
            -
            Create complex style     2.237k i/100ms
         
     | 
| 
       35 
     | 
    
         
            -
            Apply simple style (short)
         
     | 
| 
       36 
     | 
    
         
            -
                                   532.099k i/100ms
         
     | 
| 
       37 
     | 
    
         
            -
            Apply simple style (medium)
         
     | 
| 
       38 
     | 
    
         
            -
                                   502.313k i/100ms
         
     | 
| 
       39 
     | 
    
         
            -
            Apply simple style (long)
         
     | 
| 
       40 
     | 
    
         
            -
                                   488.252k i/100ms
         
     | 
| 
       41 
     | 
    
         
            -
            Apply complex style (short)
         
     | 
| 
       42 
     | 
    
         
            -
                                   375.127k i/100ms
         
     | 
| 
       43 
     | 
    
         
            -
            Apply complex style (medium)
         
     | 
| 
       44 
     | 
    
         
            -
                                   465.987k i/100ms
         
     | 
| 
       45 
     | 
    
         
            -
            Apply complex style (long)
         
     | 
| 
       46 
     | 
    
         
            -
                                   465.624k i/100ms
         
     | 
| 
       47 
     | 
    
         
            -
            Apply hex style (short)
         
     | 
| 
       48 
     | 
    
         
            -
                                   487.755k i/100ms
         
     | 
| 
       49 
     | 
    
         
            -
            Calculating -------------------------------------
         
     | 
| 
       50 
     | 
    
         
            -
             Create simple style     28.773k (± 3.1%) i/s   (34.76 μs/i) -    145.656k in   5.067273s
         
     | 
| 
       51 
     | 
    
         
            -
            Create complex style     24.042k (± 3.7%) i/s   (41.59 μs/i) -    120.798k in   5.031925s
         
     | 
| 
       52 
     | 
    
         
            -
            Apply simple style (short)
         
     | 
| 
       53 
     | 
    
         
            -
                                      5.456M (± 2.7%) i/s  (183.29 ns/i) -     27.669M in   5.075360s
         
     | 
| 
       54 
     | 
    
         
            -
            Apply simple style (medium)
         
     | 
| 
       55 
     | 
    
         
            -
                                      4.795M (± 2.8%) i/s  (208.54 ns/i) -     24.111M in   5.032058s
         
     | 
| 
       56 
     | 
    
         
            -
            Apply simple style (long)
         
     | 
| 
       57 
     | 
    
         
            -
                                      4.520M (± 5.1%) i/s  (221.24 ns/i) -     22.948M in   5.091184s
         
     | 
| 
       58 
     | 
    
         
            -
            Apply complex style (short)
         
     | 
| 
       59 
     | 
    
         
            -
                                      3.792M (± 3.6%) i/s  (263.74 ns/i) -     19.131M in   5.052424s
         
     | 
| 
       60 
     | 
    
         
            -
            Apply complex style (medium)
         
     | 
| 
       61 
     | 
    
         
            -
                                      4.633M (± 6.4%) i/s  (215.86 ns/i) -     23.299M in   5.059053s
         
     | 
| 
       62 
     | 
    
         
            -
            Apply complex style (long)
         
     | 
| 
       63 
     | 
    
         
            -
                                      4.508M (± 3.5%) i/s  (221.85 ns/i) -     22.816M in   5.068199s
         
     | 
| 
       64 
     | 
    
         
            -
            Apply hex style (short)
         
     | 
| 
       65 
     | 
    
         
            -
                                      4.534M (± 7.2%) i/s  (220.55 ns/i) -     22.924M in   5.085921s
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            Comparison:
         
     | 
| 
       68 
     | 
    
         
            -
            Apply simple style (short):  5455745.6 i/s
         
     | 
| 
       69 
     | 
    
         
            -
            Apply simple style (medium):  4795323.9 i/s - 1.14x  slower
         
     | 
| 
       70 
     | 
    
         
            -
            Apply complex style (medium):  4632694.4 i/s - 1.18x  slower
         
     | 
| 
       71 
     | 
    
         
            -
            Apply hex style (short):  4534207.7 i/s - 1.20x  slower
         
     | 
| 
       72 
     | 
    
         
            -
            Apply simple style (long):  4520017.7 i/s - 1.21x  slower
         
     | 
| 
       73 
     | 
    
         
            -
            Apply complex style (long):  4507642.6 i/s - 1.21x  slower
         
     | 
| 
       74 
     | 
    
         
            -
            Apply complex style (short):  3791544.6 i/s - 1.44x  slower
         
     | 
| 
       75 
     | 
    
         
            -
             Create simple style:    28772.5 i/s - 189.62x  slower
         
     | 
| 
       76 
     | 
    
         
            -
            Create complex style:    24041.8 i/s - 226.93x  slower
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
            Repeated Application Benchmark:
         
     | 
| 
       80 
     | 
    
         
            -
            ----------------------------------------
         
     | 
| 
       81 
     | 
    
         
            -
            Applying the same style 1000 times to measure caching benefit...
         
     | 
| 
       82 
     | 
    
         
            -
            ruby 3.2.9 (2025-07-24 revision 8f611e0c46) [arm64-darwin24]
         
     | 
| 
       83 
     | 
    
         
            -
            Warming up --------------------------------------
         
     | 
| 
       84 
     | 
    
         
            -
              1000x simple style   644.000 i/100ms
         
     | 
| 
       85 
     | 
    
         
            -
             1000x complex style   440.000 i/100ms
         
     | 
| 
       86 
     | 
    
         
            -
                 1000x hex style   542.000 i/100ms
         
     | 
| 
       87 
     | 
    
         
            -
            Calculating -------------------------------------
         
     | 
| 
       88 
     | 
    
         
            -
              1000x simple style      6.412k (± 2.6%) i/s  (155.95 μs/i) -     32.200k in   5.025177s
         
     | 
| 
       89 
     | 
    
         
            -
             1000x complex style      4.297k (± 2.5%) i/s  (232.70 μs/i) -     21.560k in   5.020173s
         
     | 
| 
       90 
     | 
    
         
            -
                 1000x hex style      5.504k (± 2.4%) i/s  (181.70 μs/i) -     27.642k in   5.025548s
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
            Comparison:
         
     | 
| 
       93 
     | 
    
         
            -
              1000x simple style:     6412.2 i/s
         
     | 
| 
       94 
     | 
    
         
            -
                 1000x hex style:     5503.6 i/s - 1.17x  slower
         
     | 
| 
       95 
     | 
    
         
            -
             1000x complex style:     4297.4 i/s - 1.49x  slower
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
            Object Allocation Analysis:
         
     | 
| 
       99 
     | 
    
         
            -
            ----------------------------------------
         
     | 
| 
       100 
     | 
    
         
            -
            Create simple style: 117 objects allocated
         
     | 
| 
       101 
     | 
    
         
            -
            Create complex style: 136 objects allocated
         
     | 
| 
       102 
     | 
    
         
            -
            Apply simple style 100x: 104 objects allocated
         
     | 
| 
       103 
     | 
    
         
            -
            Apply complex style 100x: 104 objects allocated
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
            ============================================================
         
     | 
| 
       106 
     | 
    
         
            -
            Benchmark complete!
         
     | 
| 
       107 
     | 
    
         
            -
            ============================================================
         
     | 
| 
         @@ -1,81 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            NIL? vs EMPTY? CHECK ANALYSIS
         
     | 
| 
       2 
     | 
    
         
            -
            ==============================
         
     | 
| 
       3 
     | 
    
         
            -
            Date: 2025-09-08
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            ## Implementation Comparison
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            ### Previous: empty? check
         
     | 
| 
       8 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       9 
     | 
    
         
            -
            # Initialization
         
     | 
| 
       10 
     | 
    
         
            -
            @prefix = sgr_builder.prefix_codes(...)
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            # Usage
         
     | 
| 
       13 
     | 
    
         
            -
            return text if @prefix.empty?
         
     | 
| 
       14 
     | 
    
         
            -
            ```
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            ### Current: nil? check with optimized assignment
         
     | 
| 
       17 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       18 
     | 
    
         
            -
            # Initialization  
         
     | 
| 
       19 
     | 
    
         
            -
            prefix = sgr_builder.prefix_codes(...)
         
     | 
| 
       20 
     | 
    
         
            -
            @prefix = prefix.empty? ? nil : prefix
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            # Usage
         
     | 
| 
       23 
     | 
    
         
            -
            return text unless @prefix  # equivalent to @prefix.nil?
         
     | 
| 
       24 
     | 
    
         
            -
            ```
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            ## Performance Results
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            | Metric | empty? check | nil? check | Improvement |
         
     | 
| 
       29 
     | 
    
         
            -
            |--------|-------------|------------|-------------|
         
     | 
| 
       30 
     | 
    
         
            -
            | Simple style | 5.44M/s | 5.46M/s | **+0.4% faster** |
         
     | 
| 
       31 
     | 
    
         
            -
            | Performance gain | Baseline | +22k ops/s | Marginal but positive |
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            ## Analysis
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            ### Why nil? check is (slightly) faster:
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
            1. **Simpler comparison**: `nil?` is checking against a single value (nil)
         
     | 
| 
       38 
     | 
    
         
            -
            2. **No method call**: `unless @prefix` is more direct than `@prefix.empty?`
         
     | 
| 
       39 
     | 
    
         
            -
            3. **CPU cache friendly**: nil comparisons are highly optimized in Ruby
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            ### Trade-offs:
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
            **Pros of nil? optimization:**
         
     | 
| 
       44 
     | 
    
         
            -
            - ✅ Slightly faster runtime performance
         
     | 
| 
       45 
     | 
    
         
            -
            - ✅ More direct conditional check
         
     | 
| 
       46 
     | 
    
         
            -
            - ✅ Saves one string object per empty Style (empty string not stored)
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
            **Cons of nil? optimization:**
         
     | 
| 
       49 
     | 
    
         
            -
            - ❌ Additional logic in initialization (empty? check to decide nil)
         
     | 
| 
       50 
     | 
    
         
            -
            - ❌ Slightly more complex initialization code
         
     | 
| 
       51 
     | 
    
         
            -
            - ❌ Marginal complexity increase
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            ## Memory Impact
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            ### Empty Style instances:
         
     | 
| 
       56 
     | 
    
         
            -
            - **Before**: `@prefix = ""` (empty string object)  
         
     | 
| 
       57 
     | 
    
         
            -
            - **After**: `@prefix = nil` (no string object)
         
     | 
| 
       58 
     | 
    
         
            -
            - **Savings**: ~40 bytes per empty Style instance
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
            ### Non-empty Style instances:
         
     | 
| 
       61 
     | 
    
         
            -
            - No difference in memory usage
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
            ## Recommendation
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
            **Keep the nil? optimization** because:
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            1. **Performance improvement**: Even marginal gains matter for high-frequency methods
         
     | 
| 
       68 
     | 
    
         
            -
            2. **Memory efficiency**: Eliminates empty string objects for empty Styles  
         
     | 
| 
       69 
     | 
    
         
            -
            3. **Semantic clarity**: nil clearly indicates "no styling" vs empty string
         
     | 
| 
       70 
     | 
    
         
            -
            4. **Ruby idiom**: `unless value` is more idiomatic than `if value.empty?`
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
            The initialization complexity increase is minimal and the benefits outweigh the costs.
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
            ## Final Implementation Pattern
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
            This optimization demonstrates an important pattern:
         
     | 
| 
       77 
     | 
    
         
            -
            - Transform empty values to nil during initialization
         
     | 
| 
       78 
     | 
    
         
            -
            - Use simpler nil checks at runtime
         
     | 
| 
       79 
     | 
    
         
            -
            - Trade slight initialization complexity for runtime performance
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            Perfect for performance-critical methods called frequently.
         
     | 
| 
         @@ -1,45 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # Style Caching Performance Optimization Results
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            Date: 2025-09-08  
         
     | 
| 
       4 
     | 
    
         
            -
            Issue: #5  
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            ## Files in this directory:
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            ### 1. Benchmark Script
         
     | 
| 
       9 
     | 
    
         
            -
            - `benchmark_script.rb` - Performance testing script used for all measurements
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            ### 2. Benchmark Results (in chronological order)
         
     | 
| 
       12 
     | 
    
         
            -
            - `01_baseline_results.txt` - Original performance before optimization
         
     | 
| 
       13 
     | 
    
         
            -
            - `02_with_full_caching_results.txt` - Performance with both prefix and reset_code caching
         
     | 
| 
       14 
     | 
    
         
            -
            - `03_prefix_only_caching_results.txt` - Performance with prefix caching only (no reset_code cache)
         
     | 
| 
       15 
     | 
    
         
            -
            - `06_append_operator_results.txt` - Performance with << operator instead of string interpolation
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
            ### 3. Analysis Files
         
     | 
| 
       18 
     | 
    
         
            -
            - `04_baseline_vs_optimized_analysis.txt` - Comparison between baseline and fully optimized version
         
     | 
| 
       19 
     | 
    
         
            -
            - `05_caching_approaches_comparison.txt` - Comparison between different caching strategies
         
     | 
| 
       20 
     | 
    
         
            -
            - `07_string_concatenation_comparison.txt` - String interpolation vs << operator performance analysis
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            ## Key Results Summary
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            ### Final Implementation: Full Caching with String Interpolation
         
     | 
| 
       25 
     | 
    
         
            -
            - **7-18x performance improvement** in style application
         
     | 
| 
       26 
     | 
    
         
            -
            - **85-91% reduction** in object allocations
         
     | 
| 
       27 
     | 
    
         
            -
            - **Minimal memory overhead** at creation time (6-18% increase)
         
     | 
| 
       28 
     | 
    
         
            -
            - **Best overall trade-off** for typical usage patterns
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            ### Primary Optimization Results (Included in PR)
         
     | 
| 
       31 
     | 
    
         
            -
            - **Full caching** (prefix + reset_code): Best performance
         
     | 
| 
       32 
     | 
    
         
            -
            - **Prefix-only caching**: 14-22% slower, minimal memory savings
         
     | 
| 
       33 
     | 
    
         
            -
            - **No caching** (baseline): Significantly slower, high object allocations
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            ### Additional Experiments (Reference Only)
         
     | 
| 
       36 
     | 
    
         
            -
            - **String interpolation vs << operator**: String interpolation 13-47% faster
         
     | 
| 
       37 
     | 
    
         
            -
            - **freeze optimization**: 2-4% slower (counter-productive)
         
     | 
| 
       38 
     | 
    
         
            -
            - **Constant vs caching**: Caching 1% faster with better memory usage
         
     | 
| 
       39 
     | 
    
         
            -
            - **nil? vs empty? check**: nil? optimization provides 0.4% improvement
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            ## Implementation Details
         
     | 
| 
       42 
     | 
    
         
            -
            - Cache `@prefix` and `@reset_code` in `initialize` method before `super`
         
     | 
| 
       43 
     | 
    
         
            -
            - Simplified `call` method from ~35 lines to 3 lines of string concatenation
         
     | 
| 
       44 
     | 
    
         
            -
            - Maintains identical API and immutability guarantees
         
     | 
| 
       45 
     | 
    
         
            -
            - Transforms algorithm from O(n) to O(1) per call
         
     | 
| 
         @@ -1,180 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            require "benchmark/ips"
         
     | 
| 
       5 
     | 
    
         
            -
            require "benchmark/memory"
         
     | 
| 
       6 
     | 
    
         
            -
            require "bundler/setup"
         
     | 
| 
       7 
     | 
    
         
            -
            require "tint_me"
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            # Test data
         
     | 
| 
       10 
     | 
    
         
            -
            SHORT_TEXT = "Hello"
         
     | 
| 
       11 
     | 
    
         
            -
            MEDIUM_TEXT = "The quick brown fox jumps over the lazy dog"
         
     | 
| 
       12 
     | 
    
         
            -
            LONG_TEXT = "Lorem ipsum dolor sit amet, " * 10
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            # Create various styles
         
     | 
| 
       15 
     | 
    
         
            -
            SIMPLE_STYLE = TIntMe::Style.new(foreground: :red)
         
     | 
| 
       16 
     | 
    
         
            -
            COMPLEX_STYLE = TIntMe::Style.new(
         
     | 
| 
       17 
     | 
    
         
            -
              foreground: :blue,
         
     | 
| 
       18 
     | 
    
         
            -
              background: :yellow,
         
     | 
| 
       19 
     | 
    
         
            -
              bold: true,
         
     | 
| 
       20 
     | 
    
         
            -
              italic: true,
         
     | 
| 
       21 
     | 
    
         
            -
              underline: true
         
     | 
| 
       22 
     | 
    
         
            -
            )
         
     | 
| 
       23 
     | 
    
         
            -
            HEX_STYLE = TIntMe::Style.new(
         
     | 
| 
       24 
     | 
    
         
            -
              foreground: "#FF6B35",
         
     | 
| 
       25 
     | 
    
         
            -
              background: "#F7931E",
         
     | 
| 
       26 
     | 
    
         
            -
              bold: true,
         
     | 
| 
       27 
     | 
    
         
            -
              overline: true
         
     | 
| 
       28 
     | 
    
         
            -
            )
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            puts "=" * 60
         
     | 
| 
       31 
     | 
    
         
            -
            puts "TIntMe Style Performance Benchmark"
         
     | 
| 
       32 
     | 
    
         
            -
            puts "=" * 60
         
     | 
| 
       33 
     | 
    
         
            -
            puts
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            # Memory benchmark
         
     | 
| 
       36 
     | 
    
         
            -
            puts "Memory Usage Analysis:"
         
     | 
| 
       37 
     | 
    
         
            -
            puts "-" * 40
         
     | 
| 
       38 
     | 
    
         
            -
            Benchmark.memory do |x|
         
     | 
| 
       39 
     | 
    
         
            -
              x.report("Create simple style") do
         
     | 
| 
       40 
     | 
    
         
            -
                TIntMe::Style.new(foreground: :red)
         
     | 
| 
       41 
     | 
    
         
            -
              end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
              x.report("Create complex style") do
         
     | 
| 
       44 
     | 
    
         
            -
                TIntMe::Style.new(
         
     | 
| 
       45 
     | 
    
         
            -
                  foreground: :blue,
         
     | 
| 
       46 
     | 
    
         
            -
                  background: :yellow,
         
     | 
| 
       47 
     | 
    
         
            -
                  bold: true,
         
     | 
| 
       48 
     | 
    
         
            -
                  italic: true,
         
     | 
| 
       49 
     | 
    
         
            -
                  underline: true,
         
     | 
| 
       50 
     | 
    
         
            -
                  overline: true,
         
     | 
| 
       51 
     | 
    
         
            -
                  blink: true
         
     | 
| 
       52 
     | 
    
         
            -
                )
         
     | 
| 
       53 
     | 
    
         
            -
              end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
              x.report("Apply simple style (short text)") do
         
     | 
| 
       56 
     | 
    
         
            -
                SIMPLE_STYLE.call(SHORT_TEXT)
         
     | 
| 
       57 
     | 
    
         
            -
              end
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
              x.report("Apply complex style (short text)") do
         
     | 
| 
       60 
     | 
    
         
            -
                COMPLEX_STYLE.call(SHORT_TEXT)
         
     | 
| 
       61 
     | 
    
         
            -
              end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
              x.compare!
         
     | 
| 
       64 
     | 
    
         
            -
            end
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
            puts
         
     | 
| 
       67 
     | 
    
         
            -
            puts "Performance Benchmark (operations per second):"
         
     | 
| 
       68 
     | 
    
         
            -
            puts "-" * 40
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
            Benchmark.ips do |x|
         
     | 
| 
       71 
     | 
    
         
            -
              x.config(time: 5, warmup: 2)
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
              # Style creation benchmarks
         
     | 
| 
       74 
     | 
    
         
            -
              x.report("Create simple style") do
         
     | 
| 
       75 
     | 
    
         
            -
                TIntMe::Style.new(foreground: :red)
         
     | 
| 
       76 
     | 
    
         
            -
              end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
              x.report("Create complex style") do
         
     | 
| 
       79 
     | 
    
         
            -
                TIntMe::Style.new(
         
     | 
| 
       80 
     | 
    
         
            -
                  foreground: :blue,
         
     | 
| 
       81 
     | 
    
         
            -
                  background: :yellow,
         
     | 
| 
       82 
     | 
    
         
            -
                  bold: true,
         
     | 
| 
       83 
     | 
    
         
            -
                  italic: true,
         
     | 
| 
       84 
     | 
    
         
            -
                  underline: true
         
     | 
| 
       85 
     | 
    
         
            -
                )
         
     | 
| 
       86 
     | 
    
         
            -
              end
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
              # Style application benchmarks
         
     | 
| 
       89 
     | 
    
         
            -
              x.report("Apply simple style (short)") do
         
     | 
| 
       90 
     | 
    
         
            -
                SIMPLE_STYLE.call(SHORT_TEXT)
         
     | 
| 
       91 
     | 
    
         
            -
              end
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
              x.report("Apply simple style (medium)") do
         
     | 
| 
       94 
     | 
    
         
            -
                SIMPLE_STYLE.call(MEDIUM_TEXT)
         
     | 
| 
       95 
     | 
    
         
            -
              end
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
              x.report("Apply simple style (long)") do
         
     | 
| 
       98 
     | 
    
         
            -
                SIMPLE_STYLE.call(LONG_TEXT)
         
     | 
| 
       99 
     | 
    
         
            -
              end
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
              x.report("Apply complex style (short)") do
         
     | 
| 
       102 
     | 
    
         
            -
                COMPLEX_STYLE.call(SHORT_TEXT)
         
     | 
| 
       103 
     | 
    
         
            -
              end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
              x.report("Apply complex style (medium)") do
         
     | 
| 
       106 
     | 
    
         
            -
                COMPLEX_STYLE.call(MEDIUM_TEXT)
         
     | 
| 
       107 
     | 
    
         
            -
              end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
              x.report("Apply complex style (long)") do
         
     | 
| 
       110 
     | 
    
         
            -
                COMPLEX_STYLE.call(LONG_TEXT)
         
     | 
| 
       111 
     | 
    
         
            -
              end
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
              x.report("Apply hex style (short)") do
         
     | 
| 
       114 
     | 
    
         
            -
                HEX_STYLE.call(SHORT_TEXT)
         
     | 
| 
       115 
     | 
    
         
            -
              end
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
              x.compare!
         
     | 
| 
       118 
     | 
    
         
            -
            end
         
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
            # Repeated application benchmark
         
     | 
| 
       121 
     | 
    
         
            -
            puts
         
     | 
| 
       122 
     | 
    
         
            -
            puts "Repeated Application Benchmark:"
         
     | 
| 
       123 
     | 
    
         
            -
            puts "-" * 40
         
     | 
| 
       124 
     | 
    
         
            -
            puts "Applying the same style 1000 times to measure caching benefit..."
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
            styles = [SIMPLE_STYLE, COMPLEX_STYLE, HEX_STYLE]
         
     | 
| 
       127 
     | 
    
         
            -
            style_names = %w[simple complex hex]
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
            Benchmark.ips do |x|
         
     | 
| 
       130 
     | 
    
         
            -
              x.config(time: 5, warmup: 2)
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
              styles.zip(style_names).each do |style, name|
         
     | 
| 
       133 
     | 
    
         
            -
                x.report("1000x #{name} style") do
         
     | 
| 
       134 
     | 
    
         
            -
                  1000.times { style.call(SHORT_TEXT) }
         
     | 
| 
       135 
     | 
    
         
            -
                end
         
     | 
| 
       136 
     | 
    
         
            -
              end
         
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
              x.compare!
         
     | 
| 
       139 
     | 
    
         
            -
            end
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
            # Object allocation tracking
         
     | 
| 
       142 
     | 
    
         
            -
            puts
         
     | 
| 
       143 
     | 
    
         
            -
            puts "Object Allocation Analysis:"
         
     | 
| 
       144 
     | 
    
         
            -
            puts "-" * 40
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
            # Counts object allocations during block execution
         
     | 
| 
       147 
     | 
    
         
            -
            # @return [Integer] Number of objects allocated
         
     | 
| 
       148 
     | 
    
         
            -
            def count_allocations
         
     | 
| 
       149 
     | 
    
         
            -
              before = GC.stat[:total_allocated_objects]
         
     | 
| 
       150 
     | 
    
         
            -
              yield
         
     | 
| 
       151 
     | 
    
         
            -
              after = GC.stat[:total_allocated_objects]
         
     | 
| 
       152 
     | 
    
         
            -
              after - before
         
     | 
| 
       153 
     | 
    
         
            -
            end
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
            # Measure allocations for different operations
         
     | 
| 
       156 
     | 
    
         
            -
            operations = {
         
     | 
| 
       157 
     | 
    
         
            -
              "Create simple style" => -> { TIntMe::Style.new(foreground: :red) },
         
     | 
| 
       158 
     | 
    
         
            -
              "Create complex style" => -> {
         
     | 
| 
       159 
     | 
    
         
            -
                TIntMe::Style.new(
         
     | 
| 
       160 
     | 
    
         
            -
                  foreground: :blue,
         
     | 
| 
       161 
     | 
    
         
            -
                  background: :yellow,
         
     | 
| 
       162 
     | 
    
         
            -
                  bold: true,
         
     | 
| 
       163 
     | 
    
         
            -
                  italic: true,
         
     | 
| 
       164 
     | 
    
         
            -
                  underline: true
         
     | 
| 
       165 
     | 
    
         
            -
                )
         
     | 
| 
       166 
     | 
    
         
            -
              },
         
     | 
| 
       167 
     | 
    
         
            -
              "Apply simple style 100x" => -> { 100.times { SIMPLE_STYLE.call(SHORT_TEXT) } },
         
     | 
| 
       168 
     | 
    
         
            -
              "Apply complex style 100x" => -> { 100.times { COMPLEX_STYLE.call(SHORT_TEXT) } }
         
     | 
| 
       169 
     | 
    
         
            -
            }
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
            operations.each do |name, operation|
         
     | 
| 
       172 
     | 
    
         
            -
              GC.start
         
     | 
| 
       173 
     | 
    
         
            -
              allocations = count_allocations(&operation)
         
     | 
| 
       174 
     | 
    
         
            -
              puts "#{name}: #{allocations} objects allocated"
         
     | 
| 
       175 
     | 
    
         
            -
            end
         
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
            puts
         
     | 
| 
       178 
     | 
    
         
            -
            puts "=" * 60
         
     | 
| 
       179 
     | 
    
         
            -
            puts "Benchmark complete!"
         
     | 
| 
       180 
     | 
    
         
            -
            puts "=" * 60
         
     |