rails_benchmark_suite 0.2.9 → 0.3.1
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/.gitignore +3 -1
- data/CHANGELOG.md +65 -0
- data/Gemfile.lock +29 -1
- data/README.md +103 -10
- data/bin/rails_benchmark_suite +35 -12
- data/docs/images/report_v0_3_1.png +0 -0
- data/lib/dummy/app/models/benchmark_job.rb +7 -0
- data/lib/dummy/app/models/benchmark_post.rb +9 -0
- data/lib/dummy/app/models/benchmark_user.rb +9 -0
- data/lib/dummy/app/views/rails_benchmark_suite/heft_view.html.erb +11 -0
- data/lib/dummy/config/benchmark_database.yml +16 -0
- data/lib/rails_benchmark_suite/configuration.rb +22 -0
- data/lib/rails_benchmark_suite/database_manager.rb +56 -0
- data/lib/rails_benchmark_suite/db_setup.rb +3 -0
- data/lib/rails_benchmark_suite/models/user.rb +4 -3
- data/lib/rails_benchmark_suite/reporter.rb +215 -5
- data/lib/rails_benchmark_suite/reporters/html_reporter.rb +52 -0
- data/lib/rails_benchmark_suite/runner.rb +46 -191
- data/lib/rails_benchmark_suite/schema.rb +5 -5
- data/lib/rails_benchmark_suite/templates/report.html.erb +187 -0
- data/lib/rails_benchmark_suite/version.rb +1 -1
- data/lib/rails_benchmark_suite/workload_runner.rb +158 -0
- data/lib/rails_benchmark_suite/{suites/active_record_suite.rb → workloads/active_record_workload.rb} +7 -7
- data/lib/rails_benchmark_suite/{suites/cache_heft_suite.rb → workloads/cache_heft_workload.rb} +2 -2
- data/lib/rails_benchmark_suite/{suites/image_heft_suite.rb → workloads/image_heft_workload.rb} +3 -4
- data/lib/rails_benchmark_suite/{suites/job_heft_suite.rb → workloads/job_heft_workload.rb} +4 -4
- data/lib/rails_benchmark_suite/workloads/view_heft_workload.rb +36 -0
- data/lib/rails_benchmark_suite.rb +3 -22
- data/rails_benchmark_suite.gemspec +7 -2
- metadata +92 -10
- data/lib/rails_benchmark_suite/suites/view_heft_suite.rb +0 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 473aa21869380dae81d4f9ee8668ccf161721923fd6c453cc711caf9d6303fd1
|
|
4
|
+
data.tar.gz: 5101bb8d63885263dc3fcbb8851d52f3ed48a1f919b0abfab38d43dc3f3df2a2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 11311aa76df4c103c8b3ea2e12a803ddeb339cd454127b246557341ddd5c7872fa01c4ff00f4c14ae711d95b48f0d84b148ec7f8b0a39fda7ab70cac0d070bad
|
|
7
|
+
data.tar.gz: 3f141277e2daae966aa4d7d7be684e112889fa757282e36a4f35ac34d60ac91ca76903281d9e091b9549ef567d6e8b7a26b13221326bf8273c3c33fe7e6082fc
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,69 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
## [0.3.1] - 2026-01-04
|
|
3
|
+
*Major Architectural Repair & TTY Overhaul*
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **--html**: Static HTML Reporter with Chart.js visualization.
|
|
7
|
+
- **--profile**: Automated "Scaling Efficiency" calculation (1T vs MaxT).
|
|
8
|
+
- **--db**: Real database integration (Postgres/MySQL support).
|
|
9
|
+
- **Hardware Awareness**: Auto-detection of CPU cores for thread defaults.
|
|
10
|
+
- **UI**: Rich terminal output using `tty-spinner`, `tty-table`, and `tty-box` for a dashboard-style report.
|
|
11
|
+
- **Architecture**: Implemented the standard `lib/dummy` Rails Engine pattern for internal tests.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- **Refactor**: Complete structural overhaul. Moved monolithic logic from `lib/rails_benchmark_suite.rb` into a proper namespace (`lib/rails_benchmark_suite/`).
|
|
15
|
+
- **Concurrency**: Default thread count is now dynamic (`Etc.nprocessors`) instead of hardcoded to 4.
|
|
16
|
+
- **Safety**: Renamed internal test model from `User` to `BenchmarkUser` to prevent collisions when running inside host apps.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **CLI**: Fixed the non-functional `--help` flag (now implemented via `OptionParser`).
|
|
20
|
+
- **Reporting**: Restored the "Scaling (x)" column in the final report to correctly visualize performance degradation.
|
|
21
|
+
|
|
22
|
+
## [0.3.0] - 2025-01-03
|
|
23
|
+
|
|
24
|
+
### Major Architectural Refactor (SRP)
|
|
25
|
+
- **Runner Split**: Dismantled the monolithic `Runner` class (260+ lines) into three specialized modules:
|
|
26
|
+
- `DatabaseManager`: Handles ActiveRecord connection, schema loading, and SQLite PRAGMA optimizations
|
|
27
|
+
- `WorkloadRunner`: Manages benchmark execution engine with BASE_WEIGHTS normalization and complete payload generation
|
|
28
|
+
- `Formatter`: Centralized UI rendering, ANSI colors, insights engine, and output formatting
|
|
29
|
+
- **Runner Coordinator**: `Runner` is now a minimal 23-line coordinator delegating to the three modules
|
|
30
|
+
|
|
31
|
+
### Normalized RHI Math Engine
|
|
32
|
+
- **BASE_WEIGHTS**: Defined workload weights (Active Record: 0.4, View: 0.2, Solid Queue: 0.2, Cache: 0.1, Image: 0.1)
|
|
33
|
+
- **Dynamic Weight Redistribution**: When workloads are skipped (e.g., missing libvips), weights are normalized proportionally to maintain 100% scale
|
|
34
|
+
- **Formula**: `RHI Score = Σ (4T_IPS × Adjusted_Weight)` where adjusted weights always sum to 1.0
|
|
35
|
+
|
|
36
|
+
### Performance Insights Engine
|
|
37
|
+
- **Scaling Analysis**: Warns when multi-threading scaling < 0.8x, indicating SQLite lock contention or Ruby GIL saturation
|
|
38
|
+
- **YJIT Detection**: Displays hint to enable YJIT when disabled (typical 15-25% boost)
|
|
39
|
+
- **Memory Monitoring**: Alerts when workload memory growth exceeds 20MB, suggesting heavy object allocation
|
|
40
|
+
- **Hardware Tiering**: Provides comparison labels (Entry/Dev < 50, Production-Ready 50-200, High-Performance > 200)
|
|
41
|
+
|
|
42
|
+
### UI/UX Enhancements
|
|
43
|
+
- **Box Alignment**: Fixed header and final score boxes with proper text length calculation (60-char width)
|
|
44
|
+
- **Table Spacing**: Added separator line between progress logs and results table for better readability
|
|
45
|
+
- **Insights Display**: Integrated insights below summary table with emoji indicators (💡, 📊)
|
|
46
|
+
- **Enhanced Number Formatting**: Smart k/M suffixes for readability (e.g., "15.3k", "1.2M")
|
|
47
|
+
- **YJIT Hints**: Helpful reminder `(run with RUBY_OPT="--yjit" for max perf)` when YJIT is disabled
|
|
48
|
+
- Silent migrations: Added `ActiveRecord::Migration.verbose = false` to reduce noise
|
|
49
|
+
- Cross-platform install instructions for libvips (macOS and Linux)
|
|
50
|
+
|
|
51
|
+
### 🐛 Fixes
|
|
52
|
+
- Fixed `.gitignore` to properly track `gemspec` file for gem distribution
|
|
53
|
+
- **JSON Guard**: Ensures clean JSON output without any UI noise when `--json` flag is used
|
|
54
|
+
- Improved CLI output suppression in JSON mode
|
|
55
|
+
|
|
56
|
+
### 📖 Documentation
|
|
57
|
+
- **Calculation Formula**: Added "How It's Calculated" section with RHI formula: `Σ (4-Thread IPS × Weight)`
|
|
58
|
+
- **Workload Weights Table**: Documented weights (Active Record 40%, View 20%, Jobs 20%, Cache 10%, Image 10%)
|
|
59
|
+
- **Hardware Tiers**: Explained tier classification system
|
|
60
|
+
- Complete README rewrite with four execution methods:
|
|
61
|
+
- Standard: `bundle exec rails_benchmark_suite`
|
|
62
|
+
- High Performance: `RUBY_OPT="--yjit" bundle exec rails_benchmark_suite`
|
|
63
|
+
- JSON Export: `bundle exec rails_benchmark_suite --json > report.json`
|
|
64
|
+
- Standalone: `bin/rails_benchmark_suite`
|
|
65
|
+
- Added comprehensive System Requirements section
|
|
66
|
+
- Updated all terminology from "Suite" to "Workload"
|
|
2
67
|
|
|
3
68
|
## [0.2.0] - 2025-12-31
|
|
4
69
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
rails_benchmark_suite (0.
|
|
4
|
+
rails_benchmark_suite (0.3.1)
|
|
5
5
|
actionview (~> 8.1)
|
|
6
6
|
activerecord (~> 8.1)
|
|
7
7
|
activestorage (~> 8.1)
|
|
@@ -9,7 +9,11 @@ PATH
|
|
|
9
9
|
concurrent-ruby (~> 1.3)
|
|
10
10
|
get_process_mem (~> 1.0)
|
|
11
11
|
image_processing (~> 1.14)
|
|
12
|
+
pastel (~> 0.8)
|
|
12
13
|
sqlite3 (~> 2.8)
|
|
14
|
+
tty-box (~> 0.7)
|
|
15
|
+
tty-spinner (~> 0.9)
|
|
16
|
+
tty-table (~> 0.12)
|
|
13
17
|
|
|
14
18
|
GEM
|
|
15
19
|
remote: https://rubygems.org/
|
|
@@ -116,6 +120,9 @@ GEM
|
|
|
116
120
|
racc (~> 1.4)
|
|
117
121
|
nokogiri (1.19.0-x86_64-linux-musl)
|
|
118
122
|
racc (~> 1.4)
|
|
123
|
+
ostruct (0.6.3)
|
|
124
|
+
pastel (0.8.0)
|
|
125
|
+
tty-color (~> 0.5)
|
|
119
126
|
racc (1.8.1)
|
|
120
127
|
rack (3.2.4)
|
|
121
128
|
rack-session (2.1.1)
|
|
@@ -145,9 +152,29 @@ GEM
|
|
|
145
152
|
sqlite3 (2.9.0-x86_64-darwin)
|
|
146
153
|
sqlite3 (2.9.0-x86_64-linux-gnu)
|
|
147
154
|
sqlite3 (2.9.0-x86_64-linux-musl)
|
|
155
|
+
strings (0.2.1)
|
|
156
|
+
strings-ansi (~> 0.2)
|
|
157
|
+
unicode-display_width (>= 1.5, < 3.0)
|
|
158
|
+
unicode_utils (~> 1.4)
|
|
159
|
+
strings-ansi (0.2.0)
|
|
148
160
|
timeout (0.6.0)
|
|
161
|
+
tty-box (0.7.0)
|
|
162
|
+
pastel (~> 0.8)
|
|
163
|
+
strings (~> 0.2.0)
|
|
164
|
+
tty-cursor (~> 0.7)
|
|
165
|
+
tty-color (0.6.0)
|
|
166
|
+
tty-cursor (0.7.1)
|
|
167
|
+
tty-screen (0.8.2)
|
|
168
|
+
tty-spinner (0.9.3)
|
|
169
|
+
tty-cursor (~> 0.7)
|
|
170
|
+
tty-table (0.12.0)
|
|
171
|
+
pastel (~> 0.8)
|
|
172
|
+
strings (~> 0.2.0)
|
|
173
|
+
tty-screen (~> 0.8)
|
|
149
174
|
tzinfo (2.0.6)
|
|
150
175
|
concurrent-ruby (~> 1.0)
|
|
176
|
+
unicode-display_width (2.6.0)
|
|
177
|
+
unicode_utils (1.4.0)
|
|
151
178
|
uri (1.1.1)
|
|
152
179
|
useragent (0.16.11)
|
|
153
180
|
|
|
@@ -166,6 +193,7 @@ PLATFORMS
|
|
|
166
193
|
DEPENDENCIES
|
|
167
194
|
bundler (~> 2.5)
|
|
168
195
|
minitest (~> 5.0)
|
|
196
|
+
ostruct (~> 0.6)
|
|
169
197
|
rails_benchmark_suite!
|
|
170
198
|
rake (~> 13.0)
|
|
171
199
|
|
data/README.md
CHANGED
|
@@ -26,6 +26,19 @@ The Heft Score is a weighted metric representing a machine's ability to handle R
|
|
|
26
26
|
| **150+** | 🚀 High Performance | Apple M-series Pro/Max, Ryzen 5000+ |
|
|
27
27
|
| **300+** | ⚡ Blazing | Server-grade Metal, M3 Ultra |
|
|
28
28
|
|
|
29
|
+
### 📊 Visual Reports (HTML)
|
|
30
|
+
|
|
31
|
+
Visualize your threading efficiency and bottlenecks with a self-contained dashboard:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bundle exec rails_benchmark_suite -t 8 --html
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This generates `rails_benchmark_report.html` containing:
|
|
38
|
+
- **Scaling Curve**: Interactive bar chart comparing 1-thread vs Max-thread throughput.
|
|
39
|
+
- **Efficiency Heatmap**: Score cards identifying which workloads are Gil-bound vs CPU-bound.
|
|
40
|
+
- **Detailed Metrics**: Raw IPS and detailed scaling factors.
|
|
41
|
+
|
|
29
42
|
---
|
|
30
43
|
|
|
31
44
|
## 🚀 Quick Start
|
|
@@ -56,19 +69,67 @@ Rails Benchmark Suite prioritizes **Benchmarking** (via `benchmark-ips`) over **
|
|
|
56
69
|
* **Rails:** 8.1+
|
|
57
70
|
* **Database:** SQLite3
|
|
58
71
|
|
|
59
|
-
|
|
72
|
+
## 📋 System Requirements
|
|
73
|
+
|
|
74
|
+
### Required
|
|
75
|
+
- **Ruby**: 3.3+ (3.4+ recommended for YJIT)
|
|
76
|
+
- **Rails**: 8.0+
|
|
77
|
+
- **Database**: SQLite3
|
|
78
|
+
|
|
79
|
+
### Optional (for Image Heft workload)
|
|
80
|
+
- **macOS**: `brew install vips`
|
|
81
|
+
- **Linux (Ubuntu/Debian)**: `sudo apt install libvips-dev`
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 🚀 Usage
|
|
86
|
+
|
|
87
|
+
### Standard Execution
|
|
88
|
+
```bash
|
|
89
|
+
bundle exec rails_benchmark_suite
|
|
90
|
+
```
|
|
91
|
+
The easy way - run the benchmark with your current Ruby configuration.
|
|
92
|
+
|
|
93
|
+
### High Performance (Recommended)
|
|
94
|
+
```bash
|
|
95
|
+
RUBY_OPT="--yjit" bundle exec rails_benchmark_suite
|
|
96
|
+
```
|
|
97
|
+
Enable YJIT for maximum performance measurement accuracy. This is the recommended method for Rails 8+ benchmarking.
|
|
98
|
+
|
|
99
|
+
### JSON Export (Automation)
|
|
100
|
+
```bash
|
|
101
|
+
bundle exec rails_benchmark_suite --json > report.json
|
|
102
|
+
```
|
|
103
|
+
Perfect for CI/CD pipelines and programmatic analysis. Outputs clean JSON without any UI elements.
|
|
104
|
+
|
|
105
|
+
### 📊 Visual Diagnostics (HTML Report)
|
|
106
|
+
|
|
107
|
+

|
|
60
108
|
|
|
61
|
-
|
|
109
|
+
To diagnose scaling bottlenecks, run the tool in Profile Mode (`--profile`) and generate the HTML Report (`--html`). This compares Single-Thread vs Multi-Thread performance side-by-side.
|
|
62
110
|
|
|
63
|
-
```
|
|
64
|
-
|
|
111
|
+
```bash
|
|
112
|
+
bundle exec rails_benchmark_suite --profile --html
|
|
65
113
|
```
|
|
66
114
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
115
|
+
**Opening the Report**:
|
|
116
|
+
- **Local:** `open tmp/rails_benchmark_report.html`
|
|
117
|
+
- **Remote:** `scp user@server:/current/path/tmp/rails_benchmark_report.html .`
|
|
118
|
+
|
|
119
|
+
### Command Line Options
|
|
120
|
+
|
|
121
|
+
| Flag | Description |
|
|
122
|
+
| :--- | :--- |
|
|
123
|
+
| `--html` | Generates a visual dashboard (`tmp/rails_benchmark_report.html`). **Best used with `--profile`.** |
|
|
124
|
+
| `--profile` | **Diagnostic Mode.** Runs the benchmark twice (1 Thread vs Max Threads) to calculate "Scaling Efficiency." Required to populate the "Scaling Curve" charts. |
|
|
125
|
+
| `--db` | Uses your local `config/database.yml` (Postgres/MySQL) instead of the synthetic in-memory SQLite. |
|
|
126
|
+
| `-t [N]` | Manually set the thread count (Default: Auto-detects CPU cores). |
|
|
127
|
+
|
|
128
|
+
### Configuration Flags
|
|
129
|
+
- `--json`: Output results in JSON format
|
|
130
|
+
- `--skip-rails`: Run in isolated mode without loading Rails environment
|
|
131
|
+
- `--version`: Display gem version
|
|
132
|
+
- `-h` / `--help`: Show usage help
|
|
72
133
|
|
|
73
134
|
### Standalone Usage
|
|
74
135
|
|
|
@@ -83,7 +144,39 @@ bin/rails_benchmark_suite
|
|
|
83
144
|
|
|
84
145
|
---
|
|
85
146
|
|
|
86
|
-
##
|
|
147
|
+
## 📐 How It's Calculated
|
|
148
|
+
|
|
149
|
+
The **Rails Heft Index (RHI)** measures your hardware's ability to handle Rails workloads using this formula:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
RHI Score = Σ (4-Thread IPS × Weight)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Workload Weights
|
|
156
|
+
|
|
157
|
+
| Workload | Weight | Rationale |
|
|
158
|
+
|----------|--------|-----------|
|
|
159
|
+
| **Active Record** | 40% | Database operations are the core of most Rails apps |
|
|
160
|
+
| **View Rendering** | 20% | ERB/ActionView processing |
|
|
161
|
+
| **Solid Queue** | 20% | Background job throughput |
|
|
162
|
+
| **Cache Operations** | 10% | Memory store performance |
|
|
163
|
+
| **Image Processing** | 10% | Optional - requires libvips |
|
|
164
|
+
|
|
165
|
+
**Why 4-Thread IPS?** We use 4-thread performance to simulate production concurrency where multiple requests are handled simultaneously.
|
|
166
|
+
|
|
167
|
+
**Dynamic Weight Redistribution:** If a workload is skipped (e.g., Image Processing without libvips), its weight is redistributed proportionally among remaining workloads to maintain a 100% scale.
|
|
168
|
+
|
|
169
|
+
### Hardware Tiers
|
|
170
|
+
|
|
171
|
+
Your RHI score maps to these performance tiers:
|
|
172
|
+
|
|
173
|
+
- **< 50**: Entry/Dev - Suitable for local development
|
|
174
|
+
- **50-200**: Production-Ready - Handles moderate production traffic
|
|
175
|
+
- **> 200**: High-Performance - Optimized for high-traffic applications
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 🧪 The "Heft" Workloads
|
|
87
180
|
|
|
88
181
|
The gem measures performance across critical Rails subsystems using a dedicated, isolated schema:
|
|
89
182
|
|
data/bin/rails_benchmark_suite
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "optparse"
|
|
5
|
+
require "etc"
|
|
5
6
|
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
6
7
|
require "rails_benchmark_suite"
|
|
7
8
|
require "rails_benchmark_suite/version"
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
config = RailsBenchmarkSuite::Configuration.new
|
|
11
|
+
|
|
10
12
|
OptionParser.new do |opts|
|
|
11
13
|
opts.banner = "Usage: rails_benchmark_suite [options]"
|
|
12
14
|
|
|
@@ -15,12 +17,28 @@ OptionParser.new do |opts|
|
|
|
15
17
|
exit 0
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
opts.on("-t", "--threads N", Integer, "Number of threads (default: auto set to #{Etc.nprocessors} cores)") do |n|
|
|
21
|
+
config.threads = n
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
opts.on("-p", "--profile", "Enable scaling efficiency profile mode") do
|
|
25
|
+
config.profile = true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
opts.on("-d", "--db", "Use real database from config/database.yml instead of in-memory SQLite") do
|
|
29
|
+
config.db = true
|
|
30
|
+
end
|
|
31
|
+
|
|
18
32
|
opts.on("--skip-rails", "Skip Rails environment loading") do
|
|
19
|
-
|
|
33
|
+
config.skip_rails = true
|
|
20
34
|
end
|
|
21
35
|
|
|
22
36
|
opts.on("-j", "--json", "Output results as JSON") do
|
|
23
|
-
|
|
37
|
+
config.json = true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
opts.on("--html", "Generate a visual HTML report (rails_benchmark_report.html)") do
|
|
41
|
+
config.html = true
|
|
24
42
|
end
|
|
25
43
|
|
|
26
44
|
opts.on("-h", "--help", "Prints this help") do
|
|
@@ -29,21 +47,26 @@ OptionParser.new do |opts|
|
|
|
29
47
|
end
|
|
30
48
|
end.parse!
|
|
31
49
|
|
|
32
|
-
|
|
50
|
+
unless config.json
|
|
51
|
+
puts "RailsBenchmarkSuite v#{RailsBenchmarkSuite::VERSION}"
|
|
52
|
+
puts "Configuration: Threads=#{config.threads} | Profile=#{config.profile} | Local DB=#{config.db}"
|
|
53
|
+
end
|
|
33
54
|
|
|
34
55
|
# Rails Detection
|
|
35
56
|
rails_env_path = File.join(Dir.pwd, "config", "environment.rb")
|
|
36
57
|
|
|
37
|
-
if !
|
|
38
|
-
puts "Rails environment detected at #{rails_env_path}. Loading..."
|
|
58
|
+
if !config.skip_rails && File.exist?(rails_env_path)
|
|
59
|
+
puts "Rails environment detected at #{rails_env_path}. Loading..." unless config.json
|
|
39
60
|
require rails_env_path
|
|
40
|
-
puts "Rails loaded successfully."
|
|
61
|
+
puts "Rails loaded successfully." unless config.json
|
|
41
62
|
else
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
unless config.json
|
|
64
|
+
if config.skip_rails
|
|
65
|
+
puts "Skipping Rails loading (requested via --skip-rails)."
|
|
66
|
+
else
|
|
67
|
+
puts "No Rails environment detected (config/environment.rb not found)."
|
|
68
|
+
end
|
|
46
69
|
end
|
|
47
70
|
end
|
|
48
71
|
|
|
49
|
-
RailsBenchmarkSuite.
|
|
72
|
+
RailsBenchmarkSuite::Runner.new(config).run
|
|
Binary file
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<h1>Dashboard for <%= user.name %></h1>
|
|
2
|
+
<ul>
|
|
3
|
+
<% posts.each do |post| %>
|
|
4
|
+
<li>
|
|
5
|
+
<strong><%= post.title %></strong>
|
|
6
|
+
<p><%= post.body.truncate(50) %></p>
|
|
7
|
+
<small>Views: <%= number_with_delimiter(post.views) %></small>
|
|
8
|
+
</li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
<footer>Generated at <%= Time.now.to_s %></footer>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Dummy DB Config for isolated benchmarking
|
|
2
|
+
test:
|
|
3
|
+
adapter: sqlite3
|
|
4
|
+
database: ":memory:"
|
|
5
|
+
pool: 50
|
|
6
|
+
timeout: 5000
|
|
7
|
+
|
|
8
|
+
development:
|
|
9
|
+
adapter: sqlite3
|
|
10
|
+
database: "file:dummy_bench.sqlite3?mode=memory&cache=shared"
|
|
11
|
+
pool: 50
|
|
12
|
+
timeout: 30000
|
|
13
|
+
# High performance settings
|
|
14
|
+
variables:
|
|
15
|
+
journal_mode: WAL
|
|
16
|
+
synchronous: NORMAL
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "etc"
|
|
4
|
+
|
|
5
|
+
module RailsBenchmarkSuite
|
|
6
|
+
class Configuration
|
|
7
|
+
attr_accessor :threads, :profile, :db, :skip_rails, :json, :html
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@threads = Etc.nprocessors
|
|
11
|
+
@profile = false
|
|
12
|
+
@db = false
|
|
13
|
+
@skip_rails = false
|
|
14
|
+
@json = false
|
|
15
|
+
@html = false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def db_mode
|
|
19
|
+
@db ? "Local DB" : "SQLite (Memory)"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_record"
|
|
4
|
+
require "yaml"
|
|
5
|
+
|
|
6
|
+
module RailsBenchmarkSuite
|
|
7
|
+
class DatabaseManager
|
|
8
|
+
SETUP_MUTEX = Mutex.new
|
|
9
|
+
|
|
10
|
+
def setup(use_local_db: false)
|
|
11
|
+
# Silence migrations
|
|
12
|
+
ActiveRecord::Migration.verbose = false
|
|
13
|
+
|
|
14
|
+
if use_local_db
|
|
15
|
+
setup_real_database
|
|
16
|
+
else
|
|
17
|
+
setup_dummy_database
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def setup_real_database
|
|
24
|
+
config_path = File.join(Dir.pwd, "config", "database.yml")
|
|
25
|
+
unless File.exist?(config_path)
|
|
26
|
+
raise "Database config not found at #{config_path} (required for --db option)"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
db_config = YAML.load_file(config_path)
|
|
30
|
+
env = defined?(Rails) ? Rails.env : "development"
|
|
31
|
+
|
|
32
|
+
ActiveRecord::Base.establish_connection(db_config[env])
|
|
33
|
+
puts "Connected to local database (#{env})"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def setup_dummy_database
|
|
37
|
+
# Load internal dummy config
|
|
38
|
+
config_path = File.expand_path("../dummy/config/benchmark_database.yml", __dir__)
|
|
39
|
+
db_config = YAML.load_file(config_path)
|
|
40
|
+
|
|
41
|
+
# Use "development" profile which has the PRAGMA optimizations
|
|
42
|
+
ActiveRecord::Base.establish_connection(db_config["development"])
|
|
43
|
+
|
|
44
|
+
# Apply manual optimizations if needed (though config should handle it)
|
|
45
|
+
conn = ActiveRecord::Base.connection.raw_connection
|
|
46
|
+
conn.busy_timeout = 10000
|
|
47
|
+
|
|
48
|
+
# Setup Schema once safely
|
|
49
|
+
SETUP_MUTEX.synchronize do
|
|
50
|
+
unless ActiveRecord::Base.connection.table_exists?(:benchmark_users)
|
|
51
|
+
RailsBenchmarkSuite::Schema.load
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "rails_benchmark_suite/dummy/app/models/benchmark_user"
|
|
4
|
+
require "rails_benchmark_suite/dummy/app/models/benchmark_post"
|
|
5
|
+
|
|
3
6
|
module RailsBenchmarkSuite
|
|
4
7
|
module Models
|
|
5
|
-
|
|
6
|
-
has_many :posts, class_name: "RailsBenchmarkSuite::Models::Post", dependent: :destroy
|
|
7
|
-
end
|
|
8
|
+
# Proxy or Legacy support if needed, but primary logic is now in Dummy namespace
|
|
8
9
|
end
|
|
9
10
|
end
|