type_balancer 0.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.
@@ -0,0 +1,55 @@
1
+ + cd /app
2
+ + bundle exec ruby -I lib benchmark/end_to_end_benchmark.rb
3
+ Ruby version: 3.2.8
4
+ RUBY_PLATFORM: aarch64-linux
5
+ YJIT enabled: false
6
+
7
+ Running benchmarks...
8
+
9
+ Benchmarking Tiny Dataset (10 items)
10
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
11
+ Warming up --------------------------------------
12
+ Ruby Implementation 5.815k i/100ms
13
+ Calculating -------------------------------------
14
+ Ruby Implementation 70.626k (± 8.1%) i/s (14.16 μs/i) - 145.375k in 2.072857s
15
+
16
+ Distribution Stats:
17
+ Video: 4 (40.0%)
18
+ Image: 3 (30.0%)
19
+ Article: 3 (30.0%)
20
+
21
+ Benchmarking Small Dataset (100 items)
22
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
23
+ Warming up --------------------------------------
24
+ Ruby Implementation 179.000 i/100ms
25
+ Calculating -------------------------------------
26
+ Ruby Implementation 1.904k (± 4.8%) i/s (525.33 μs/i) - 3.938k in 2.073542s
27
+
28
+ Distribution Stats:
29
+ Video: 34 (34.0%)
30
+ Image: 33 (33.0%)
31
+ Article: 33 (33.0%)
32
+
33
+ Benchmarking Medium Dataset (1000 items)
34
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
35
+ Warming up --------------------------------------
36
+ Ruby Implementation 1.000 i/100ms
37
+ Calculating -------------------------------------
38
+ Ruby Implementation 20.785 (± 9.6%) i/s (48.11 ms/i) - 62.000 in 3.018630s
39
+
40
+ Distribution Stats:
41
+ Video: 334 (33.4%)
42
+ Image: 333 (33.3%)
43
+ Article: 333 (33.3%)
44
+
45
+ Benchmarking Large Dataset (10000 items)
46
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
47
+ Warming up --------------------------------------
48
+ Ruby Implementation 1.000 i/100ms
49
+ Calculating -------------------------------------
50
+ Ruby Implementation 0.229 (± 0.0%) i/s (4.37 s/i) - 1.000 in 4.371704s
51
+
52
+ Distribution Stats:
53
+ Video: 3334 (33.34%)
54
+ Image: 3333 (33.33%)
55
+ Article: 3333 (33.33%)
@@ -0,0 +1,55 @@
1
+ + cd /app
2
+ + bundle exec ruby -I lib benchmark/end_to_end_benchmark.rb
3
+ Ruby version: 3.2.8
4
+ RUBY_PLATFORM: aarch64-linux
5
+ YJIT enabled: false
6
+
7
+ Running benchmarks...
8
+
9
+ Benchmarking Tiny Dataset (10 items)
10
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
11
+ Warming up --------------------------------------
12
+ Ruby Implementation 8.136k i/100ms
13
+ Calculating -------------------------------------
14
+ Ruby Implementation 74.212k (± 6.1%) i/s (13.47 μs/i) - 154.584k in 2.090755s
15
+
16
+ Distribution Stats:
17
+ Video: 4 (40.0%)
18
+ Image: 3 (30.0%)
19
+ Article: 3 (30.0%)
20
+
21
+ Benchmarking Small Dataset (100 items)
22
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
23
+ Warming up --------------------------------------
24
+ Ruby Implementation 181.000 i/100ms
25
+ Calculating -------------------------------------
26
+ Ruby Implementation 1.934k (± 4.9%) i/s (517.12 μs/i) - 3.982k in 2.064193s
27
+
28
+ Distribution Stats:
29
+ Video: 34 (34.0%)
30
+ Image: 33 (33.0%)
31
+ Article: 33 (33.0%)
32
+
33
+ Benchmarking Medium Dataset (1000 items)
34
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
35
+ Warming up --------------------------------------
36
+ Ruby Implementation 1.000 i/100ms
37
+ Calculating -------------------------------------
38
+ Ruby Implementation 18.611 (±16.1%) i/s (53.73 ms/i) - 54.000 in 3.010201s
39
+
40
+ Distribution Stats:
41
+ Video: 334 (33.4%)
42
+ Image: 333 (33.3%)
43
+ Article: 333 (33.3%)
44
+
45
+ Benchmarking Large Dataset (10000 items)
46
+ ruby 3.2.8 (2025-03-26 revision 13f495dc2c) [aarch64-linux]
47
+ Warming up --------------------------------------
48
+ Ruby Implementation 1.000 i/100ms
49
+ Calculating -------------------------------------
50
+ Ruby Implementation 0.227 (± 0.0%) i/s (4.41 s/i) - 1.000 in 4.405356s
51
+
52
+ Distribution Stats:
53
+ Video: 3334 (33.34%)
54
+ Image: 3333 (33.33%)
55
+ Article: 3333 (33.33%)
@@ -0,0 +1,55 @@
1
+ + cd /app
2
+ + bundle exec ruby -I lib benchmark/end_to_end_benchmark.rb
3
+ Ruby version: 3.3.7
4
+ RUBY_PLATFORM: aarch64-linux
5
+ YJIT enabled: false
6
+
7
+ Running benchmarks...
8
+
9
+ Benchmarking Tiny Dataset (10 items)
10
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
11
+ Warming up --------------------------------------
12
+ Ruby Implementation 6.917k i/100ms
13
+ Calculating -------------------------------------
14
+ Ruby Implementation 66.848k (± 4.7%) i/s (14.96 μs/i) - 138.340k in 2.074218s
15
+
16
+ Distribution Stats:
17
+ Video: 4 (40.0%)
18
+ Image: 3 (30.0%)
19
+ Article: 3 (30.0%)
20
+
21
+ Benchmarking Small Dataset (100 items)
22
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
23
+ Warming up --------------------------------------
24
+ Ruby Implementation 174.000 i/100ms
25
+ Calculating -------------------------------------
26
+ Ruby Implementation 1.897k (± 4.5%) i/s (527.03 μs/i) - 3.828k in 2.021687s
27
+
28
+ Distribution Stats:
29
+ Video: 34 (34.0%)
30
+ Image: 33 (33.0%)
31
+ Article: 33 (33.0%)
32
+
33
+ Benchmarking Medium Dataset (1000 items)
34
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
35
+ Warming up --------------------------------------
36
+ Ruby Implementation 2.000 i/100ms
37
+ Calculating -------------------------------------
38
+ Ruby Implementation 19.511 (±10.3%) i/s (51.25 ms/i) - 58.000 in 3.018480s
39
+
40
+ Distribution Stats:
41
+ Video: 334 (33.4%)
42
+ Image: 333 (33.3%)
43
+ Article: 333 (33.3%)
44
+
45
+ Benchmarking Large Dataset (10000 items)
46
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
47
+ Warming up --------------------------------------
48
+ Ruby Implementation 1.000 i/100ms
49
+ Calculating -------------------------------------
50
+ Ruby Implementation 0.224 (± 0.0%) i/s (4.46 s/i) - 1.000 in 4.464788s
51
+
52
+ Distribution Stats:
53
+ Video: 3334 (33.34%)
54
+ Image: 3333 (33.33%)
55
+ Article: 3333 (33.33%)
@@ -0,0 +1,55 @@
1
+ + cd /app
2
+ + bundle exec ruby -I lib benchmark/end_to_end_benchmark.rb
3
+ Ruby version: 3.3.7
4
+ RUBY_PLATFORM: aarch64-linux
5
+ YJIT enabled: false
6
+
7
+ Running benchmarks...
8
+
9
+ Benchmarking Tiny Dataset (10 items)
10
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
11
+ Warming up --------------------------------------
12
+ Ruby Implementation 6.343k i/100ms
13
+ Calculating -------------------------------------
14
+ Ruby Implementation 66.941k (± 6.0%) i/s (14.94 μs/i) - 139.546k in 2.092006s
15
+
16
+ Distribution Stats:
17
+ Video: 4 (40.0%)
18
+ Image: 3 (30.0%)
19
+ Article: 3 (30.0%)
20
+
21
+ Benchmarking Small Dataset (100 items)
22
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
23
+ Warming up --------------------------------------
24
+ Ruby Implementation 175.000 i/100ms
25
+ Calculating -------------------------------------
26
+ Ruby Implementation 1.888k (± 5.1%) i/s (529.71 μs/i) - 3.850k in 2.044860s
27
+
28
+ Distribution Stats:
29
+ Video: 34 (34.0%)
30
+ Image: 33 (33.0%)
31
+ Article: 33 (33.0%)
32
+
33
+ Benchmarking Medium Dataset (1000 items)
34
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
35
+ Warming up --------------------------------------
36
+ Ruby Implementation 1.000 i/100ms
37
+ Calculating -------------------------------------
38
+ Ruby Implementation 19.923 (±15.1%) i/s (50.19 ms/i) - 59.000 in 3.031767s
39
+
40
+ Distribution Stats:
41
+ Video: 334 (33.4%)
42
+ Image: 333 (33.3%)
43
+ Article: 333 (33.3%)
44
+
45
+ Benchmarking Large Dataset (10000 items)
46
+ ruby 3.3.7 (2025-01-15 revision be31f993d7) [aarch64-linux]
47
+ Warming up --------------------------------------
48
+ Ruby Implementation 1.000 i/100ms
49
+ Calculating -------------------------------------
50
+ Ruby Implementation 0.224 (± 0.0%) i/s (4.47 s/i) - 1.000 in 4.467441s
51
+
52
+ Distribution Stats:
53
+ Video: 3334 (33.34%)
54
+ Image: 3333 (33.33%)
55
+ Article: 3333 (33.33%)
@@ -0,0 +1,55 @@
1
+ + cd /app
2
+ + bundle exec ruby -I lib benchmark/end_to_end_benchmark.rb
3
+ Ruby version: 3.4.2
4
+ RUBY_PLATFORM: aarch64-linux
5
+ YJIT enabled: false
6
+
7
+ Running benchmarks...
8
+
9
+ Benchmarking Tiny Dataset (10 items)
10
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
11
+ Warming up --------------------------------------
12
+ Ruby Implementation 6.476k i/100ms
13
+ Calculating -------------------------------------
14
+ Ruby Implementation 66.552k (± 5.7%) i/s (15.03 μs/i) - 135.996k in 2.050038s
15
+
16
+ Distribution Stats:
17
+ Video: 4 (40.0%)
18
+ Image: 3 (30.0%)
19
+ Article: 3 (30.0%)
20
+
21
+ Benchmarking Small Dataset (100 items)
22
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
23
+ Warming up --------------------------------------
24
+ Ruby Implementation 168.000 i/100ms
25
+ Calculating -------------------------------------
26
+ Ruby Implementation 1.790k (± 5.2%) i/s (558.74 μs/i) - 3.696k in 2.070989s
27
+
28
+ Distribution Stats:
29
+ Video: 34 (34.0%)
30
+ Image: 33 (33.0%)
31
+ Article: 33 (33.0%)
32
+
33
+ Benchmarking Medium Dataset (1000 items)
34
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
35
+ Warming up --------------------------------------
36
+ Ruby Implementation 1.000 i/100ms
37
+ Calculating -------------------------------------
38
+ Ruby Implementation 19.043 (±10.5%) i/s (52.51 ms/i) - 57.000 in 3.042588s
39
+
40
+ Distribution Stats:
41
+ Video: 334 (33.4%)
42
+ Image: 333 (33.3%)
43
+ Article: 333 (33.3%)
44
+
45
+ Benchmarking Large Dataset (10000 items)
46
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
47
+ Warming up --------------------------------------
48
+ Ruby Implementation 1.000 i/100ms
49
+ Calculating -------------------------------------
50
+ Ruby Implementation 0.212 (± 0.0%) i/s (4.71 s/i) - 1.000 in 4.711867s
51
+
52
+ Distribution Stats:
53
+ Video: 3334 (33.34%)
54
+ Image: 3333 (33.33%)
55
+ Article: 3333 (33.33%)
@@ -0,0 +1,55 @@
1
+ + cd /app
2
+ + bundle exec ruby -I lib benchmark/end_to_end_benchmark.rb
3
+ Ruby version: 3.4.2
4
+ RUBY_PLATFORM: aarch64-linux
5
+ YJIT enabled: false
6
+
7
+ Running benchmarks...
8
+
9
+ Benchmarking Tiny Dataset (10 items)
10
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
11
+ Warming up --------------------------------------
12
+ Ruby Implementation 6.784k i/100ms
13
+ Calculating -------------------------------------
14
+ Ruby Implementation 66.579k (± 4.7%) i/s (15.02 μs/i) - 135.680k in 2.042522s
15
+
16
+ Distribution Stats:
17
+ Video: 4 (40.0%)
18
+ Image: 3 (30.0%)
19
+ Article: 3 (30.0%)
20
+
21
+ Benchmarking Small Dataset (100 items)
22
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
23
+ Warming up --------------------------------------
24
+ Ruby Implementation 168.000 i/100ms
25
+ Calculating -------------------------------------
26
+ Ruby Implementation 1.768k (± 6.2%) i/s (565.69 μs/i) - 3.528k in 2.003878s
27
+
28
+ Distribution Stats:
29
+ Video: 34 (34.0%)
30
+ Image: 33 (33.0%)
31
+ Article: 33 (33.0%)
32
+
33
+ Benchmarking Medium Dataset (1000 items)
34
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
35
+ Warming up --------------------------------------
36
+ Ruby Implementation 1.000 i/100ms
37
+ Calculating -------------------------------------
38
+ Ruby Implementation 19.919 (± 5.0%) i/s (50.20 ms/i) - 60.000 in 3.023325s
39
+
40
+ Distribution Stats:
41
+ Video: 334 (33.4%)
42
+ Image: 333 (33.3%)
43
+ Article: 333 (33.3%)
44
+
45
+ Benchmarking Large Dataset (10000 items)
46
+ ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [aarch64-linux]
47
+ Warming up --------------------------------------
48
+ Ruby Implementation 1.000 i/100ms
49
+ Calculating -------------------------------------
50
+ Ruby Implementation 0.212 (± 0.0%) i/s (4.71 s/i) - 1.000 in 4.706258s
51
+
52
+ Distribution Stats:
53
+ Video: 3334 (33.34%)
54
+ Image: 3333 (33.33%)
55
+ Article: 3333 (33.33%)
@@ -0,0 +1,180 @@
1
+ # Benchmark Documentation
2
+
3
+ This document provides detailed information about TypeBalancer's performance benchmarks, including methodology, environment setup, and comprehensive results across different Ruby versions.
4
+
5
+ ## Methodology
6
+
7
+ ### Test Environment
8
+
9
+ - Hardware: ARM64 (aarch64) Linux environment
10
+ - Ruby Versions:
11
+ - Ruby 3.2.8
12
+ - Ruby 3.3.7
13
+ - Ruby 3.4.2
14
+ - YJIT: Both enabled and disabled configurations tested
15
+ - Docker containers used for consistent testing environment
16
+
17
+ ### Test Scenarios
18
+
19
+ Each benchmark test evaluates performance across different collection sizes, from small content feeds to large-scale collections:
20
+
21
+ 1. Tiny Dataset (Content Widget):
22
+ - Total Items: 10
23
+ - Distribution: Video (40%), Image (30%), Article (30%)
24
+ - Processing Time: ~12 microseconds
25
+
26
+ 2. Small Dataset (Content Feed):
27
+ - Total Items: 100
28
+ - Distribution: Video (34%), Image (33%), Article (33%)
29
+ - Processing Time: ~464 microseconds
30
+
31
+ 3. Medium Dataset (Category Page):
32
+ - Total Items: 1,000
33
+ - Distribution: Video (33.4%), Image (33.3%), Article (33.3%)
34
+ - Processing Time: ~19 milliseconds
35
+
36
+ 4. Large Dataset (Site-wide Content):
37
+ - Total Items: 10,000
38
+ - Distribution: Video (33.34%), Image (33.33%), Article (33.33%)
39
+ - Processing Time: ~191 milliseconds
40
+
41
+ ### Real-world Application
42
+
43
+ TypeBalancer is designed for practical use in content management and display systems:
44
+ - Process 10,000 items in under 200ms
45
+ - Maintain perfect distribution ratios
46
+ - Suitable for real-time web applications
47
+ - Efficient enough for on-the-fly content organization
48
+
49
+ ### Measurement Approach
50
+
51
+ - Each test scenario is run multiple times to ensure statistical significance
52
+ - Both wall-clock time and CPU time are measured
53
+ - Results include operations per second and time per operation
54
+ - Benchmark-ips gem used for iterations per second calculations
55
+ - Performance measured across different Ruby versions and configurations
56
+
57
+ ## Detailed Results
58
+
59
+ ### Ruby 3.4.2 Performance (with PRISM)
60
+
61
+ | Metric | Tiny Dataset | Small Dataset | Medium Dataset | Large Dataset |
62
+ |--------|--------------|---------------|----------------|---------------|
63
+ | Speed (no YJIT) | 73.3K ops/sec | 2.0K ops/sec | 46.9 ops/sec | 4.8 ops/sec |
64
+ | Speed (YJIT) | 102.0K ops/sec | 2.1K ops/sec | 46.2 ops/sec | 4.8 ops/sec |
65
+ | Time/Op (no YJIT) | 13.63 μs | 494.84 μs | 21.34 ms | 207.62 ms |
66
+ | Time/Op (YJIT) | 9.80 μs | 478.05 μs | 21.64 ms | 208.85 ms |
67
+ | YJIT Impact | +39.1% | +3.5% | -1.4% | -0.6% |
68
+ | Distribution Quality | Perfect | Excellent | Excellent | Excellent |
69
+
70
+ ### Ruby 3.3.7 Performance
71
+
72
+ | Metric | Tiny Dataset | Small Dataset | Medium Dataset | Large Dataset |
73
+ |--------|--------------|---------------|----------------|---------------|
74
+ | Speed (no YJIT) | 74.8K ops/sec | 2.1K ops/sec | 49.2 ops/sec | 5.1 ops/sec |
75
+ | Speed (YJIT) | 108.1K ops/sec | 2.3K ops/sec | 48.8 ops/sec | 5.2 ops/sec |
76
+ | Time/Op (no YJIT) | 13.37 μs | 477.95 μs | 20.34 ms | 196.05 ms |
77
+ | Time/Op (YJIT) | 9.25 μs | 437.36 μs | 20.49 ms | 193.08 ms |
78
+ | YJIT Impact | +44.5% | +9.3% | -0.7% | +1.5% |
79
+ | Distribution Quality | Perfect | Excellent | Excellent | Excellent |
80
+
81
+ ### Ruby 3.2.8 Performance
82
+
83
+ | Metric | Tiny Dataset | Small Dataset | Medium Dataset | Large Dataset |
84
+ |--------|--------------|---------------|----------------|---------------|
85
+ | Speed (no YJIT) | 72.2K ops/sec | 2.2K ops/sec | 46.3 ops/sec | 4.7 ops/sec |
86
+ | Speed (YJIT) | 108.8K ops/sec | 2.2K ops/sec | 47.3 ops/sec | 5.2 ops/sec |
87
+ | Time/Op (no YJIT) | 13.86 μs | 451.35 μs | 21.59 ms | 215.04 ms |
88
+ | Time/Op (YJIT) | 9.19 μs | 449.99 μs | 21.15 ms | 193.67 ms |
89
+ | YJIT Impact | +50.8% | +0.3% | +2.1% | +11.0% |
90
+ | Distribution Quality | Perfect | Excellent | Excellent | Excellent |
91
+
92
+ ## Analysis
93
+
94
+ ### Performance Characteristics
95
+
96
+ 1. Speed and Efficiency:
97
+ - Processes 10K items in ~200ms across all Ruby versions
98
+ - Microsecond-level processing for small collections (9-14μs)
99
+ - Millisecond-level processing for large collections (193-209ms)
100
+ - YJIT provides significant speedup for tiny datasets (39-51% faster)
101
+ - Suitable for real-time web applications
102
+
103
+ 2. YJIT Impact:
104
+ - Most effective on tiny datasets (10 items)
105
+ - Benefits diminish as dataset size increases
106
+ - Ruby 3.2.8 shows most consistent YJIT improvements
107
+ - Some versions show slight regressions on larger datasets
108
+
109
+ 3. Distribution Quality:
110
+ - Perfect distribution in small datasets
111
+ - Highly accurate distribution in larger datasets
112
+ - Consistent quality across all Ruby versions and YJIT settings
113
+
114
+ ### Scaling Characteristics
115
+
116
+ 1. Dataset Size Impact:
117
+ - Predictable performance scaling with size
118
+ - Sub-second processing even for large datasets
119
+ - Reliable performance characteristics
120
+
121
+ 2. Memory Usage:
122
+ - Efficient memory utilization
123
+ - Predictable memory patterns
124
+ - Stable across different workloads
125
+
126
+ 3. Distribution Quality:
127
+ - Maintains high accuracy at all scales
128
+ - Improves with larger datasets
129
+ - Consistent across implementations
130
+
131
+ ## Use Cases
132
+
133
+ 1. Content Management Systems:
134
+ - Homepage feeds (100s of items): < 1ms processing
135
+ - Category pages (1000s of items): ~20ms processing
136
+ - Site-wide content (10,000s of items): ~200ms processing
137
+
138
+ 2. Real-time Applications:
139
+ - Widget content balancing: microsecond response
140
+ - Feed generation: sub-millisecond processing
141
+ - Content reorganization: real-time capable
142
+
143
+ 3. Batch Processing:
144
+ - Large collection processing: efficient and reliable
145
+ - Consistent performance characteristics
146
+ - Predictable resource usage
147
+
148
+ ## Conclusions
149
+
150
+ 1. Version Selection:
151
+ - Ruby 3.2.8 shows optimal performance
152
+ - All versions maintain high distribution quality
153
+ - Version choice can be based on other requirements
154
+
155
+ 2. Production Readiness:
156
+ - Suitable for production workloads
157
+ - Handles large datasets efficiently
158
+ - Real-time processing capable
159
+
160
+ 3. Future Outlook:
161
+ - Continued optimization for larger datasets
162
+ - Focus on maintaining distribution quality
163
+ - Performance improvements in newer Ruby versions
164
+
165
+ ## Running the Benchmarks
166
+
167
+ To run these benchmarks in your environment:
168
+
169
+ ```bash
170
+ # Run all benchmarks
171
+ ./bin/run_benchmarks.sh
172
+
173
+ # Run for specific platform
174
+ ./bin/run_benchmarks.sh --platform linux/arm64
175
+
176
+ # Run for specific Ruby version
177
+ ./bin/run_benchmarks.sh --version 3.2.8
178
+ ```
179
+
180
+ Results will be saved in the `benchmark_results` directory.
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'type_balancer'
4
+
5
+ class QualityChecker
6
+ def initialize
7
+ @issues = []
8
+ @examples_run = 0
9
+ @examples_passed = 0
10
+ end
11
+
12
+ def run
13
+ check_basic_distribution
14
+ check_available_items
15
+ check_edge_cases
16
+ check_real_world_feed
17
+
18
+ print_summary
19
+ exit(@issues.empty? ? 0 : 1)
20
+ end
21
+
22
+ private
23
+
24
+ def record_issue(message)
25
+ @issues << message
26
+ end
27
+
28
+ def check_basic_distribution
29
+ @examples_run += 1
30
+ puts "\nBasic Distribution Example:"
31
+ positions = TypeBalancer.calculate_positions(total_count: 10, ratio: 0.3)
32
+
33
+ if positions == [0, 5, 9]
34
+ @examples_passed += 1
35
+ else
36
+ record_issue("Basic distribution positions #{positions.inspect} don't match expected [0, 5, 9]")
37
+ end
38
+
39
+ spacing = positions&.each_cons(2)&.map { |a, b| b - a }
40
+ puts "Positions for 3 items across 10 slots: #{positions.inspect}"
41
+ puts "Spacing between positions: #{spacing.inspect}"
42
+
43
+ return unless spacing != [5, 4]
44
+
45
+ record_issue("Basic distribution spacing #{spacing.inspect} isn't optimal [5, 4]")
46
+ end
47
+
48
+ def check_available_items
49
+ @examples_run += 1
50
+ puts "\nAvailable Items Example:"
51
+ positions = TypeBalancer.calculate_positions(
52
+ total_count: 10,
53
+ ratio: 0.5,
54
+ available_items: [0, 1, 2]
55
+ )
56
+
57
+ if positions == [0, 1, 2]
58
+ @examples_passed += 1
59
+ else
60
+ record_issue("Available items test returned #{positions.inspect} instead of expected [0, 1, 2]")
61
+ end
62
+
63
+ puts "Positions when only 3 slots available: #{positions.inspect}"
64
+ end
65
+
66
+ def check_edge_cases
67
+ puts "\nEdge Cases:"
68
+
69
+ # Single item
70
+ @examples_run += 1
71
+ single = TypeBalancer.calculate_positions(total_count: 1, ratio: 1.0)
72
+ puts "Single item: #{single.inspect}"
73
+ if single == [0]
74
+ @examples_passed += 1
75
+ else
76
+ record_issue("Single item case returned #{single.inspect} instead of [0]")
77
+ end
78
+
79
+ # No items
80
+ @examples_run += 1
81
+ none = TypeBalancer.calculate_positions(total_count: 100, ratio: 0.0)
82
+ puts "No items needed: #{none.inspect}"
83
+ if none == []
84
+ @examples_passed += 1
85
+ else
86
+ record_issue("Zero ratio case returned #{none.inspect} instead of []")
87
+ end
88
+
89
+ # All items
90
+ @examples_run += 1
91
+ all = TypeBalancer.calculate_positions(total_count: 5, ratio: 1.0)
92
+ puts "All items needed: #{all.inspect}"
93
+ if all == [0, 1, 2, 3, 4]
94
+ @examples_passed += 1
95
+ else
96
+ record_issue("Full ratio case returned #{all.inspect} instead of [0, 1, 2, 3, 4]")
97
+ end
98
+ end
99
+
100
+ def check_real_world_feed
101
+ @examples_run += 1
102
+ puts "\nReal World Example - Content Feed:"
103
+ feed_size = 20
104
+
105
+ # Track allocated positions
106
+ allocated_positions = []
107
+ content_positions = {}
108
+
109
+ # Calculate positions for each type
110
+ content_positions[:video] = TypeBalancer.calculate_positions(
111
+ total_count: feed_size,
112
+ ratio: 0.3,
113
+ available_items: (0..7).to_a - allocated_positions
114
+ )
115
+ allocated_positions += content_positions[:video]
116
+
117
+ content_positions[:image] = TypeBalancer.calculate_positions(
118
+ total_count: feed_size,
119
+ ratio: 0.4,
120
+ available_items: (0..14).to_a - allocated_positions
121
+ )
122
+ allocated_positions += content_positions[:image]
123
+
124
+ content_positions[:article] = TypeBalancer.calculate_positions(
125
+ total_count: feed_size,
126
+ ratio: 0.3,
127
+ available_items: (0..19).to_a - allocated_positions
128
+ )
129
+
130
+ puts "\nContent Type Positions:"
131
+ content_positions.each do |type, pos|
132
+ puts "#{type}: #{pos.inspect}"
133
+ end
134
+
135
+ # Check for overlaps
136
+ all_positions = content_positions.values.compact.flatten
137
+ if all_positions == all_positions.uniq
138
+ puts "\nSuccess: No overlapping positions!"
139
+ @examples_passed += 1
140
+ else
141
+ overlaps = all_positions.group_by { |e| e }.select { |_, v| v.size > 1 }.keys
142
+ record_issue("Found overlapping positions at indices: #{overlaps.inspect}")
143
+ puts "\nWarning: Some positions overlap!"
144
+ end
145
+
146
+ # Verify distribution
147
+ puts "\nDistribution Stats:"
148
+ expected_counts = { video: 6, image: 8, article: 6 }
149
+ content_positions.each do |type, positions|
150
+ count = positions&.length || 0
151
+ percentage = (count.to_f / feed_size * 100).round(1)
152
+ puts "#{type}: #{count} items (#{percentage}% of feed)"
153
+
154
+ if count != expected_counts[type]
155
+ record_issue("#{type} count #{count} doesn't match expected #{expected_counts[type]}")
156
+ end
157
+ end
158
+ end
159
+
160
+ def print_summary
161
+ puts "\n#{'-' * 50}"
162
+ puts 'Quality Check Summary:'
163
+ puts "Examples Run: #{@examples_run}"
164
+ puts "Examples Passed: #{@examples_passed}"
165
+
166
+ if @issues.empty?
167
+ puts "\nAll quality checks passed! ✓"
168
+ else
169
+ puts "\nQuality check failed with #{@issues.size} issues:"
170
+ @issues.each_with_index do |issue, index|
171
+ puts "#{index + 1}. #{issue}"
172
+ end
173
+ end
174
+ puts "#{'-' * 50}"
175
+ end
176
+ end
177
+
178
+ QualityChecker.new.run