tint_me 1.0.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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop_todo.yml +7 -0
  3. data/.serena/project.yml +68 -0
  4. data/.simplecov +24 -0
  5. data/.yardopts +6 -0
  6. data/AGENTS.md +60 -0
  7. data/CHANGELOG.md +29 -0
  8. data/CLAUDE.md +1 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +175 -0
  11. data/RELEASING.md +202 -0
  12. data/Rakefile +18 -0
  13. data/benchmark/2025-09-08-style-caching-optimization/01_baseline_results.txt +39 -0
  14. data/benchmark/2025-09-08-style-caching-optimization/02_with_full_caching_results.txt +54 -0
  15. data/benchmark/2025-09-08-style-caching-optimization/03_prefix_only_caching_results.txt +107 -0
  16. data/benchmark/2025-09-08-style-caching-optimization/04_baseline_vs_optimized_analysis.txt +65 -0
  17. data/benchmark/2025-09-08-style-caching-optimization/05_caching_approaches_comparison.txt +59 -0
  18. data/benchmark/2025-09-08-style-caching-optimization/06_append_operator_results.txt +107 -0
  19. data/benchmark/2025-09-08-style-caching-optimization/07_string_concatenation_comparison.txt +66 -0
  20. data/benchmark/2025-09-08-style-caching-optimization/08_with_freeze_optimization_results.txt +107 -0
  21. data/benchmark/2025-09-08-style-caching-optimization/09_freeze_optimization_analysis.txt +49 -0
  22. data/benchmark/2025-09-08-style-caching-optimization/10_constant_access_results.txt +107 -0
  23. data/benchmark/2025-09-08-style-caching-optimization/11_constant_vs_cache_analysis.txt +74 -0
  24. data/benchmark/2025-09-08-style-caching-optimization/12_empty_prefix_analysis.txt +81 -0
  25. data/benchmark/2025-09-08-style-caching-optimization/13_nil_check_optimization_results.txt +107 -0
  26. data/benchmark/2025-09-08-style-caching-optimization/14_nil_vs_empty_check_analysis.txt +81 -0
  27. data/benchmark/2025-09-08-style-caching-optimization/README.md +45 -0
  28. data/benchmark/2025-09-08-style-caching-optimization/benchmark_script.rb +180 -0
  29. data/docs/agents/git-pr.md +298 -0
  30. data/docs/agents/languages.md +388 -0
  31. data/docs/agents/rubocop.md +55 -0
  32. data/lib/tint_me/error.rb +6 -0
  33. data/lib/tint_me/sgr_builder.rb +259 -0
  34. data/lib/tint_me/style/schema.rb +22 -0
  35. data/lib/tint_me/style/types.rb +50 -0
  36. data/lib/tint_me/style.rb +286 -0
  37. data/lib/tint_me/version.rb +8 -0
  38. data/lib/tint_me.rb +62 -0
  39. data/mise.toml +5 -0
  40. data/sig/tint_me.rbs +61 -0
  41. metadata +131 -0
@@ -0,0 +1,54 @@
1
+ OPTIMIZED BENCHMARK RESULTS (After Caching Implementation)
2
+ ==========================================================
3
+ Date: 2025-09-08
4
+
5
+ ## Performance Summary
6
+
7
+ ### Style Application (operations/second)
8
+ - Simple style: ~5.44M ops/s (184ns per call)
9
+ - Complex style: ~3.83M ops/s (261ns per call)
10
+ - Hex color style: ~4.66M ops/s (215ns per call)
11
+
12
+ ### Repeated Application (1000x)
13
+ - Simple style: 6,383 ops/s (157μs total)
14
+ - Complex style: 4,294 ops/s (233μs total)
15
+ - Hex style: 5,343 ops/s (187μs total)
16
+
17
+ ### Memory Usage
18
+ - Simple style creation: 6.1KB, 58 objects (+350 bytes, +6 objects)
19
+ - Complex style creation: 7.8KB, 79 objects (+1.2KB, +13 objects)
20
+ - Simple style application: 424 bytes, 3 objects
21
+ - Complex style application: 264 bytes, 2 objects
22
+
23
+ ### Object Allocations (100 applications)
24
+ - Simple style: 104 objects (85% reduction)
25
+ - Complex style: 104 objects (91% reduction)
26
+
27
+ ## Performance Improvements
28
+
29
+ ### Speed Improvements
30
+ - Simple style: 7.1x faster (766k → 5.44M ops/s)
31
+ - Complex style: 8.8x faster (437k → 3.83M ops/s)
32
+ - Hex color style: 17.5x faster (266k → 4.66M ops/s)
33
+
34
+ ### Object Allocation Reductions
35
+ - Simple style: 85% fewer objects (703 → 104)
36
+ - Complex style: 91% fewer objects (1203 → 104)
37
+
38
+ ### Repeated Application Improvements
39
+ - Simple style: 8.2x faster (781 → 6,383 ops/s)
40
+ - Complex style: 9.9x faster (433 → 4,294 ops/s)
41
+ - Hex style: 20.2x faster (265 → 5,343 ops/s)
42
+
43
+ ## Memory Trade-offs
44
+ - Style creation memory increase: 6-18% higher
45
+ - Per-application memory usage: Dramatically reduced
46
+ - Overall memory efficiency: Much better for repeated use
47
+
48
+ ## Key Observations
49
+
50
+ 1. **Massive performance gains**: 7-18x faster style application
51
+ 2. **Dramatic allocation reduction**: 85-91% fewer objects
52
+ 3. **Consistent performance**: Style complexity no longer impacts speed significantly
53
+ 4. **Memory trade-off acceptable**: Small creation overhead, huge runtime savings
54
+ 5. **Hex colors now fast**: RGB conversion cached at creation time
@@ -0,0 +1,107 @@
1
+ ============================================================
2
+ TIntMe Style Performance Benchmark
3
+ ============================================================
4
+
5
+ Memory Usage Analysis:
6
+ ----------------------------------------
7
+ Calculating -------------------------------------
8
+ Create simple style 6.048k memsize ( 0.000 retained)
9
+ 58.000 objects ( 0.000 retained)
10
+ 2.000 strings ( 0.000 retained)
11
+ Create complex style 7.744k 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
+ 616.000 memsize ( 0.000 retained)
16
+ 4.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): 616 allocated - 2.33x more
26
+ Create simple style: 6048 allocated - 22.91x more
27
+ Create complex style: 7744 allocated - 29.33x 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.927k i/100ms
34
+ Create complex style 2.413k i/100ms
35
+ Apply simple style (short)
36
+ 443.590k i/100ms
37
+ Apply simple style (medium)
38
+ 395.847k i/100ms
39
+ Apply simple style (long)
40
+ 378.681k i/100ms
41
+ Apply complex style (short)
42
+ 321.759k i/100ms
43
+ Apply complex style (medium)
44
+ 382.195k i/100ms
45
+ Apply complex style (long)
46
+ 356.585k i/100ms
47
+ Apply hex style (short)
48
+ 373.664k i/100ms
49
+ Calculating -------------------------------------
50
+ Create simple style 29.037k (± 3.1%) i/s (34.44 μs/i) - 146.350k in 5.045026s
51
+ Create complex style 24.894k (± 1.7%) i/s (40.17 μs/i) - 125.476k in 5.042000s
52
+ Apply simple style (short)
53
+ 4.428M (± 0.8%) i/s (225.85 ns/i) - 22.180M in 5.009439s
54
+ Apply simple style (medium)
55
+ 3.847M (± 1.4%) i/s (259.95 ns/i) - 19.397M in 5.043123s
56
+ Apply simple style (long)
57
+ 3.764M (± 1.6%) i/s (265.69 ns/i) - 18.934M in 5.031865s
58
+ Apply complex style (short)
59
+ 3.275M (± 1.0%) i/s (305.32 ns/i) - 16.410M in 5.010664s
60
+ Apply complex style (medium)
61
+ 3.748M (± 4.8%) i/s (266.82 ns/i) - 18.728M in 5.012920s
62
+ Apply complex style (long)
63
+ 3.469M (± 5.5%) i/s (288.30 ns/i) - 17.473M in 5.056096s
64
+ Apply hex style (short)
65
+ 3.747M (± 3.1%) i/s (266.90 ns/i) - 19.057M in 5.092324s
66
+
67
+ Comparison:
68
+ Apply simple style (short): 4427800.1 i/s
69
+ Apply simple style (medium): 3846907.6 i/s - 1.15x slower
70
+ Apply simple style (long): 3763792.3 i/s - 1.18x slower
71
+ Apply complex style (medium): 3747858.3 i/s - 1.18x slower
72
+ Apply hex style (short): 3746719.7 i/s - 1.18x slower
73
+ Apply complex style (long): 3468603.6 i/s - 1.28x slower
74
+ Apply complex style (short): 3275289.7 i/s - 1.35x slower
75
+ Create simple style: 29037.4 i/s - 152.49x slower
76
+ Create complex style: 24894.1 i/s - 177.87x 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 497.000 i/100ms
85
+ 1000x complex style 357.000 i/100ms
86
+ 1000x hex style 426.000 i/100ms
87
+ Calculating -------------------------------------
88
+ 1000x simple style 4.961k (± 0.9%) i/s (201.59 μs/i) - 24.850k in 5.009943s
89
+ 1000x complex style 3.553k (± 3.4%) i/s (281.45 μs/i) - 17.850k in 5.031381s
90
+ 1000x hex style 4.171k (± 5.0%) i/s (239.76 μs/i) - 20.874k in 5.019703s
91
+
92
+ Comparison:
93
+ 1000x simple style: 4960.5 i/s
94
+ 1000x hex style: 4170.9 i/s - 1.19x slower
95
+ 1000x complex style: 3553.0 i/s - 1.40x 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
+ ============================================================
@@ -0,0 +1,65 @@
1
+ PERFORMANCE COMPARISON ANALYSIS
2
+ ===============================
3
+
4
+ ## Before vs After Optimization Summary
5
+
6
+ ### Style Application Performance (ops/second)
7
+ | Style Type | Before | After | Improvement |
8
+ |------------|-----------|-----------|-------------|
9
+ | Simple | 766,000 | 5,444,000 | 7.1x faster |
10
+ | Complex | 437,000 | 3,834,000 | 8.8x faster |
11
+ | Hex Color | 266,000 | 4,656,000 | 17.5x faster|
12
+
13
+ ### Repeated Application (1000x, ops/second)
14
+ | Style Type | Before | After | Improvement |
15
+ |------------|--------|-------|-------------|
16
+ | Simple | 781 | 6,383 | 8.2x faster |
17
+ | Complex | 433 | 4,294 | 9.9x faster |
18
+ | Hex | 265 | 5,343 | 20.2x faster|
19
+
20
+ ### Object Allocations (100 applications)
21
+ | Style Type | Before | After | Reduction |
22
+ |------------|--------|-------|-----------|
23
+ | Simple | 703 | 104 | 85% less |
24
+ | Complex | 1,203 | 104 | 91% less |
25
+
26
+ ### Memory Usage Per Style Creation
27
+ | Style Type | Before | After | Increase |
28
+ |------------|---------------|---------------|----------|
29
+ | Simple | 5.8KB, 52 obj| 6.1KB, 58 obj | +6% |
30
+ | Complex | 6.6KB, 66 obj| 7.8KB, 79 obj | +18% |
31
+
32
+ ## Key Insights
33
+
34
+ ### Performance Gains
35
+ 1. **Hex colors see biggest improvement**: 17.5-20x faster
36
+ - RGB conversion now happens once at creation instead of every call
37
+
38
+ 2. **Complex styles benefit most**: 8.8-9.9x faster
39
+ - Multiple SGR parameters cached as single string
40
+
41
+ 3. **Simple styles still significant**: 7.1-8.2x faster
42
+ - Even basic styles benefit from eliminating repeated calculation
43
+
44
+ ### Memory Trade-offs
45
+ 1. **Creation cost acceptable**: 6-18% increase in creation memory
46
+ - Small price for immutable objects that may be called many times
47
+
48
+ 2. **Runtime memory much better**: Massive reduction in per-call allocations
49
+ - 85-91% fewer objects created during style application
50
+
51
+ 3. **Net positive for typical usage**: Any style called >2-3 times benefits
52
+
53
+ ### Algorithm Complexity Improvements
54
+ 1. **Before**: O(n) per call where n = number of style attributes
55
+ 2. **After**: O(1) per call - just string concatenation
56
+ 3. **One-time cost**: SGR sequence building moved to initialization
57
+
58
+ ## Recommendation
59
+ The optimization is highly successful with minimal downsides:
60
+ - Dramatic performance improvements across all scenarios
61
+ - Acceptable memory trade-off for creation
62
+ - Maintains identical API and behavior
63
+ - Especially beneficial for repeated use (the common case)
64
+
65
+ This change transforms Style from a computation-heavy operation to a simple string concatenation, making it suitable for high-frequency styling operations.
@@ -0,0 +1,59 @@
1
+ CACHING APPROACH COMPARISON
2
+ ===========================
3
+ Date: 2025-09-08
4
+
5
+ ## Memory Usage Comparison (Style Creation)
6
+
7
+ ### With reset_code caching:
8
+ - Simple style: 6.1KB, 58 objects
9
+ - Complex style: 7.8KB, 79 objects
10
+
11
+ ### Without reset_code caching:
12
+ - Simple style: 6.0KB, 58 objects (-8 bytes)
13
+ - Complex style: 7.7KB, 79 objects (-8 bytes)
14
+
15
+ **Memory savings: ~8 bytes per Style instance (negligible)**
16
+
17
+ ## Performance Comparison (ops/second)
18
+
19
+ ### Style Application Performance:
20
+ | Style Type | With reset_code cache | Without reset_code cache | Difference |
21
+ |------------|----------------------|---------------------------|------------|
22
+ | Simple | 5.44M | 4.43M | 18% slower |
23
+ | Complex | 3.83M | 3.28M | 14% slower |
24
+ | Hex | 4.66M | 3.75M | 20% slower |
25
+
26
+ ### Repeated Application (1000x):
27
+ | Style Type | With cache | Without cache | Difference |
28
+ |------------|------------|---------------|------------|
29
+ | Simple | 6,383 | 4,961 | 22% slower |
30
+ | Complex | 4,294 | 3,553 | 17% slower |
31
+ | Hex | 5,343 | 4,171 | 22% slower |
32
+
33
+ ### Memory Usage Per Application:
34
+ | Style Type | With cache | Without cache | Difference |
35
+ |------------|------------|---------------|------------|
36
+ | Simple | 424 bytes | 616 bytes | +45% more |
37
+ | Complex | 264 bytes | 264 bytes | same |
38
+
39
+ ## Analysis
40
+
41
+ ### Performance Impact:
42
+ - **14-22% performance decrease** without reset_code caching
43
+ - Simple styles show highest impact (22% slower)
44
+ - Memory allocation per call increases for simple styles
45
+
46
+ ### Memory Trade-off:
47
+ - **Minimal creation savings**: Only 8 bytes per Style instance
48
+ - **Higher runtime cost**: Simple styles use 45% more memory per call
49
+ - **Net negative**: More allocations during frequent usage
50
+
51
+ ### Recommendations:
52
+
53
+ **Keep reset_code caching** because:
54
+ 1. Negligible memory savings (8 bytes) when removed
55
+ 2. Significant performance cost (14-22% slower)
56
+ 3. Increased runtime memory allocations
57
+ 4. Reset code is a constant string ("\e[0m") - perfect for caching
58
+
59
+ The reset_code caching provides substantial performance benefits with minimal memory overhead, making it an optimal trade-off for the typical use case of applying styles multiple times.
@@ -0,0 +1,107 @@
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.537k i/100ms
34
+ Create complex style 2.341k i/100ms
35
+ Apply simple style (short)
36
+ 466.725k i/100ms
37
+ Apply simple style (medium)
38
+ 341.328k i/100ms
39
+ Apply simple style (long)
40
+ 287.127k i/100ms
41
+ Apply complex style (short)
42
+ 323.061k i/100ms
43
+ Apply complex style (medium)
44
+ 336.757k i/100ms
45
+ Apply complex style (long)
46
+ 303.412k i/100ms
47
+ Apply hex style (short)
48
+ 237.369k i/100ms
49
+ Calculating -------------------------------------
50
+ Create simple style 28.350k (± 3.5%) i/s (35.27 μs/i) - 142.072k in 5.018115s
51
+ Create complex style 22.956k (± 8.6%) i/s (43.56 μs/i) - 114.709k in 5.048226s
52
+ Apply simple style (short)
53
+ 4.604M (± 1.7%) i/s (217.20 ns/i) - 23.336M in 5.069941s
54
+ Apply simple style (medium)
55
+ 3.365M (± 3.7%) i/s (297.21 ns/i) - 17.066M in 5.080576s
56
+ Apply simple style (long)
57
+ 3.071M (± 4.5%) i/s (325.67 ns/i) - 15.505M in 5.059977s
58
+ Apply complex style (short)
59
+ 3.362M (± 4.0%) i/s (297.41 ns/i) - 16.799M in 5.006339s
60
+ Apply complex style (medium)
61
+ 3.337M (± 1.8%) i/s (299.70 ns/i) - 16.838M in 5.047809s
62
+ Apply complex style (long)
63
+ 3.027M (± 6.1%) i/s (330.32 ns/i) - 15.171M in 5.032030s
64
+ Apply hex style (short)
65
+ 2.473M (± 1.8%) i/s (404.40 ns/i) - 12.581M in 5.089276s
66
+
67
+ Comparison:
68
+ Apply simple style (short): 4604142.2 i/s
69
+ Apply simple style (medium): 3364580.5 i/s - 1.37x slower
70
+ Apply complex style (short): 3362358.4 i/s - 1.37x slower
71
+ Apply complex style (medium): 3336720.3 i/s - 1.38x slower
72
+ Apply simple style (long): 3070605.6 i/s - 1.50x slower
73
+ Apply complex style (long): 3027356.7 i/s - 1.52x slower
74
+ Apply hex style (short): 2472779.1 i/s - 1.86x slower
75
+ Create simple style: 28349.6 i/s - 162.41x slower
76
+ Create complex style: 22956.2 i/s - 200.56x 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 528.000 i/100ms
85
+ 1000x complex style 362.000 i/100ms
86
+ 1000x hex style 238.000 i/100ms
87
+ Calculating -------------------------------------
88
+ 1000x simple style 5.013k (± 7.6%) i/s (199.47 μs/i) - 25.344k in 5.092091s
89
+ 1000x complex style 3.694k (± 2.3%) i/s (270.71 μs/i) - 18.462k in 5.000406s
90
+ 1000x hex style 2.608k (± 5.6%) i/s (383.40 μs/i) - 13.090k in 5.040010s
91
+
92
+ Comparison:
93
+ 1000x simple style: 5013.4 i/s
94
+ 1000x complex style: 3694.0 i/s - 1.36x slower
95
+ 1000x hex style: 2608.3 i/s - 1.92x 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
+ ============================================================
@@ -0,0 +1,66 @@
1
+ STRING CONCATENATION METHOD COMPARISON
2
+ ======================================
3
+ Date: 2025-09-08
4
+
5
+ ## Performance Comparison: String Interpolation vs << Operator
6
+
7
+ ### Method Implementations
8
+
9
+ #### String Interpolation (Original)
10
+ ```ruby
11
+ def call(text)
12
+ return text if @prefix.empty?
13
+ "#{@prefix}#{text}#{@reset_code}"
14
+ end
15
+ ```
16
+
17
+ #### << Operator (Experimental)
18
+ ```ruby
19
+ def call(text)
20
+ return text if @prefix.empty?
21
+ @prefix.dup << text << @reset_code
22
+ end
23
+ ```
24
+
25
+ ### Performance Results (ops/second)
26
+
27
+ | Style Type | String Interpolation | << Operator | Performance Loss |
28
+ |------------|---------------------|-------------|------------------|
29
+ | Simple | 5.44M/s | 4.55M/s | **16% slower** |
30
+ | Complex | 3.83M/s | 3.35M/s | **13% slower** |
31
+ | Hex Color | 4.66M/s | 2.45M/s | **47% slower** |
32
+
33
+ ### Memory Usage (per application)
34
+
35
+ | Implementation | Simple Style | Complex Style |
36
+ |----------------|-------------|---------------|
37
+ | String Interpolation | 424 bytes, 3 objects | 264 bytes, 2 objects |
38
+ | << Operator | 424 bytes, 3 objects | 264 bytes, 2 objects |
39
+
40
+ *Memory usage appears identical*
41
+
42
+ ### Analysis
43
+
44
+ #### Why << Operator is Slower:
45
+
46
+ 1. **Extra Copy Cost**: `@prefix.dup` creates unnecessary string copy
47
+ 2. **Multiple Operations**: Three separate `<<` calls vs single interpolation
48
+ 3. **Ruby Optimization**: String interpolation is highly optimized in Ruby
49
+ 4. **Hex Colors Impact**: Most significant performance hit (47% slower)
50
+
51
+ #### Performance Loss Breakdown:
52
+
53
+ - **Simple styles**: 16% slower due to dup + concatenation overhead
54
+ - **Complex styles**: 13% slower, similar pattern
55
+ - **Hex colors**: 47% slower, suggests interpolation especially optimized for longer strings
56
+
57
+ ### Conclusion
58
+
59
+ **String interpolation (`"#{a}#{b}#{c}"`) is definitively superior** for this use case:
60
+
61
+ - Consistently faster across all style types
62
+ - No additional memory allocation overhead
63
+ - Leverages Ruby's built-in string interpolation optimizations
64
+ - Simpler, more readable code
65
+
66
+ The experiment confirms that the original implementation choice was optimal. Ruby's string interpolation is highly optimized and should be preferred over manual concatenation methods for performance-critical string building operations.
@@ -0,0 +1,107 @@
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.829k i/100ms
34
+ Create complex style 2.405k i/100ms
35
+ Apply simple style (short)
36
+ 551.851k i/100ms
37
+ Apply simple style (medium)
38
+ 476.907k i/100ms
39
+ Apply simple style (long)
40
+ 482.203k i/100ms
41
+ Apply complex style (short)
42
+ 381.682k i/100ms
43
+ Apply complex style (medium)
44
+ 455.559k i/100ms
45
+ Apply complex style (long)
46
+ 417.965k i/100ms
47
+ Apply hex style (short)
48
+ 470.351k i/100ms
49
+ Calculating -------------------------------------
50
+ Create simple style 27.161k (± 6.4%) i/s (36.82 μs/i) - 135.792k in 5.024378s
51
+ Create complex style 23.009k (± 4.3%) i/s (43.46 μs/i) - 115.440k in 5.027763s
52
+ Apply simple style (short)
53
+ 5.264M (± 3.8%) i/s (189.96 ns/i) - 26.489M in 5.039995s
54
+ Apply simple style (medium)
55
+ 4.621M (± 3.1%) i/s (216.40 ns/i) - 23.368M in 5.061823s
56
+ Apply simple style (long)
57
+ 4.478M (± 4.8%) i/s (223.34 ns/i) - 22.664M in 5.074611s
58
+ Apply complex style (short)
59
+ 3.685M (± 2.4%) i/s (271.36 ns/i) - 18.702M in 5.078168s
60
+ Apply complex style (medium)
61
+ 4.536M (± 4.8%) i/s (220.45 ns/i) - 22.778M in 5.036293s
62
+ Apply complex style (long)
63
+ 4.271M (± 7.5%) i/s (234.13 ns/i) - 21.316M in 5.031500s
64
+ Apply hex style (short)
65
+ 4.558M (± 3.7%) i/s (219.39 ns/i) - 23.047M in 5.063931s
66
+
67
+ Comparison:
68
+ Apply simple style (short): 5264329.5 i/s
69
+ Apply simple style (medium): 4621101.0 i/s - 1.14x slower
70
+ Apply hex style (short): 4558064.1 i/s - 1.15x slower
71
+ Apply complex style (medium): 4536089.7 i/s - 1.16x slower
72
+ Apply simple style (long): 4477533.0 i/s - 1.18x slower
73
+ Apply complex style (long): 4271132.9 i/s - 1.23x slower
74
+ Apply complex style (short): 3685074.9 i/s - 1.43x slower
75
+ Create simple style: 27161.3 i/s - 193.82x slower
76
+ Create complex style: 23008.5 i/s - 228.80x 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 631.000 i/100ms
85
+ 1000x complex style 412.000 i/100ms
86
+ 1000x hex style 540.000 i/100ms
87
+ Calculating -------------------------------------
88
+ 1000x simple style 6.203k (± 2.1%) i/s (161.20 μs/i) - 31.550k in 5.088346s
89
+ 1000x complex style 4.119k (± 5.2%) i/s (242.77 μs/i) - 20.600k in 5.018834s
90
+ 1000x hex style 5.267k (± 2.8%) i/s (189.85 μs/i) - 26.460k in 5.027249s
91
+
92
+ Comparison:
93
+ 1000x simple style: 6203.3 i/s
94
+ 1000x hex style: 5267.4 i/s - 1.18x slower
95
+ 1000x complex style: 4119.1 i/s - 1.51x 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: 103 objects allocated
103
+ Apply complex style 100x: 103 objects allocated
104
+
105
+ ============================================================
106
+ Benchmark complete!
107
+ ============================================================
@@ -0,0 +1,49 @@
1
+ FREEZE OPTIMIZATION ANALYSIS
2
+ =============================
3
+ Date: 2025-09-08
4
+
5
+ ## Implementation Change
6
+
7
+ Added `.freeze` to the cached prefix string:
8
+
9
+ ```ruby
10
+ # Before
11
+ @prefix = sgr_builder.prefix_codes(...)
12
+
13
+ # After
14
+ @prefix = sgr_builder.prefix_codes(...).freeze
15
+ ```
16
+
17
+ ## Performance Comparison
18
+
19
+ | Style Type | Without freeze | With freeze | Difference |
20
+ |------------|----------------|-------------|------------|
21
+ | Simple | 5.44M/s | 5.26M/s | **3% slower** |
22
+ | Complex | 3.83M/s | 3.69M/s | **4% slower** |
23
+ | Hex Color | 4.66M/s | 4.56M/s | **2% slower** |
24
+
25
+ ## Analysis
26
+
27
+ ### Why freeze didn't help (and slightly hurt):
28
+
29
+ 1. **String interpolation doesn't modify strings**: The operation `"#{@prefix}#{text}#{@reset_code}"` creates a new string without modifying the original strings, so freeze protection isn't needed.
30
+
31
+ 2. **Freeze call overhead**: The `.freeze` method call during initialization adds slight overhead without providing benefits for this use case.
32
+
33
+ 3. **Data.define already provides immutability**: The Style instance itself is frozen after `super`, providing sufficient protection.
34
+
35
+ 4. **Memory allocation patterns unchanged**: Freeze doesn't affect how string interpolation allocates memory.
36
+
37
+ ### When freeze would be beneficial:
38
+
39
+ - If we were doing destructive operations like `@prefix << something`
40
+ - If the strings were being passed to untrusted code
41
+ - If we needed to prevent accidental modification in other parts of the codebase
42
+
43
+ ## Conclusion
44
+
45
+ **Remove the freeze optimization** - it provides no performance benefit and adds unnecessary overhead.
46
+
47
+ The original implementation without explicit freezing is optimal for this use case. Ruby's string interpolation is already highly optimized and doesn't require the strings to be frozen for maximum performance.
48
+
49
+ **Recommendation**: Revert to the non-frozen version for best performance.