fastruby/fast-ruby
:dash: Writing Fast Ruby :heart_eyes: -- Collect Common Ruby idioms.
Slowing — last commit 4mo ago
worst of 4 axesno license — legally unclear; no tests detected
no license — can't legally use code; no tests detected
Documented and popular — useful reference codebase to read through.
no license — can't legally use code
- ✓Last commit 4mo ago
- ✓39+ active contributors
- ✓Distributed ownership (top contributor 16% of recent commits)
Show 4 more →Show less
- ✓CI configured
- ⚠Slowing — last commit 4mo ago
- ⚠No license — legally unclear to depend on
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: publish a permissive license (MIT, Apache-2.0, etc.)
- →Fork & modify Concerns → Mixed if: add a LICENSE file
- →Deploy as-is Concerns → Mixed if: add a LICENSE file
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/fastruby/fast-ruby)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/fastruby/fast-ruby on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: fastruby/fast-ruby
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/fastruby/fast-ruby shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Slowing — last commit 4mo ago
- Last commit 4mo ago
- 39+ active contributors
- Distributed ownership (top contributor 16% of recent commits)
- CI configured
- ⚠ Slowing — last commit 4mo ago
- ⚠ No license — legally unclear to depend on
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live fastruby/fast-ruby
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/fastruby/fast-ruby.
What it runs against: a local clone of fastruby/fast-ruby — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in fastruby/fast-ruby | Confirms the artifact applies here, not a fork |
| 2 | Default branch main exists | Catches branch renames |
| 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 4 | Last commit ≤ 162 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of fastruby/fast-ruby. If you don't
# have one yet, run these first:
#
# git clone https://github.com/fastruby/fast-ruby.git
# cd fast-ruby
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of fastruby/fast-ruby and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "fastruby/fast-ruby(\\.git)?\\b" \\
&& ok "origin remote is fastruby/fast-ruby" \\
|| miss "origin remote is not fastruby/fast-ruby (artifact may be from a fork)"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "README.md" \\
&& ok "README.md" \\
|| miss "missing critical file: README.md"
test -f "Rakefile" \\
&& ok "Rakefile" \\
|| miss "missing critical file: Rakefile"
test -f ".github/workflows/benchmarks.yml" \\
&& ok ".github/workflows/benchmarks.yml" \\
|| miss "missing critical file: .github/workflows/benchmarks.yml"
test -f "CONTRIBUTING.md" \\
&& ok "CONTRIBUTING.md" \\
|| miss "missing critical file: CONTRIBUTING.md"
test -f "code/general" \\
&& ok "code/general" \\
|| miss "missing critical file: code/general"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 162 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~132d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/fastruby/fast-ruby"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
fast-ruby is a curated collection of Ruby performance idioms and benchmarks that documents real-world optimizations. It compares functionally equivalent Ruby code patterns (e.g., attr_accessor vs manual getter/setter, map.flatten vs flat_map, merge vs merge!) with executable benchmark suites using benchmark-ips, helping developers choose faster implementations based on measured data rather than assumptions. Simple, flat directory structure: code/ contains subdirectories by category (array/, date/, enumerable/, general/, hash/, string/, time/, range/) with each idiom as a standalone .rb file (e.g., code/array/sort-reverse-vs-sort_by-with-block.rb). Each file is a complete, runnable benchmark script using the benchmark-ips template. Documentation is centralized in README.md with results aggregated from GitHub Actions workflows.
👥Who it's for
Ruby developers and technical leads who want to optimize hot paths in production code. Specifically: maintainers of performance-critical gems, Rails application engineers tuning database query results processing, and teams using the fasterer static analyzer to lint their codebases for performance anti-patterns.
🌱Maturity & risk
Actively maintained and production-ready. The repo has GitHub Actions CI running benchmarks against multiple Ruby versions, recent commits (latest visible in workflows), and comprehensive documentation with 36K+ lines of Ruby code organized into clear categories (array, enumerable, hash, string, etc.). The project is well-established enough to be referenced in Erik Michaels-Ober's 'Writing Fast Ruby' talk and has inspired the fasterer linter project.
Very low risk. No external dependencies beyond benchmark-ips (a standard benchmarking gem). The repo is purely educational/reference code—no binary distributions, no breaking API changes, and each idiom file is self-contained. Single-maintainer concern is mitigated by the simple, static nature of the content (benchmarks don't require frequent maintenance as long as Ruby semantics remain stable).
Active areas of work
Continuous benchmark execution via .github/workflows/benchmarks.yml against Ruby 4.0.0 on macOS 15.6.1. The README shows recent results (Ruby 4.0.0, Dec 2024) comparing implementation speeds with explicit i/s metrics and slowdown factors. Active monitoring of Ruby version compatibility across GitHub Actions matrices.
🚀Get running
git clone https://github.com/fastruby/fast-ruby.git
cd fast-ruby
bundle install
ruby code/general/attr-accessor-vs-getter-and-setter.rb
Daily commands:
Execute individual benchmark files directly: ruby code/array/array-concat-vs-+.rb or run all via Rake: bundle exec rake (check Rakefile for available tasks). Results are auto-generated and published to GitHub Actions workflow artifacts.
🗺️Map of the codebase
README.md— Essential entry point documenting all Ruby performance idioms, benchmarking results, and the repo's mission—every contributor must understand the project scope and format.Rakefile— Build and benchmark orchestration script that runs performance tests across all idiom files—contributors need to know how to execute and validate benchmarks..github/workflows/benchmarks.yml— CI/CD pipeline that automatically runs benchmarks on each commit—critical for understanding how changes are validated and reported.CONTRIBUTING.md— Contribution guidelines specifying how to add new idiom comparisons and maintain consistency—mandatory for all new submissions.code/general— Core general-purpose Ruby idiom examples that serve as a reference template for structure and format across all other categories.
🛠️How to make changes
Add a new Ruby idiom comparison
- Create a new .rb file in the appropriate subdirectory (e.g., code/array/, code/string/) following the naming pattern: fast-option-vs-slow-option.rb (
code/array/new-idiom-example.rb) - Structure the file with two benchmarking groups using the Benchmark.ips format, one for the fast idiom and one for the slow idiom, with clear variable setup (
code/array/array-concat-vs-+.rb) - Document the idiom in README.md by adding an entry under the appropriate category with the benchmark results, explanation, and real-world commit links (
README.md) - Run the Rakefile task to generate benchmarks and verify your new idiom appears in automated reports (
Rakefile)
Update benchmark results for a new Ruby version
- Update the Ruby version specification in the Gemfile or configuration (
Gemfile) - Execute the Rakefile benchmark task to re-run all idiom comparisons against the new Ruby version (
Rakefile) - Update the README.md with the new benchmark results, noting the Ruby version and machine specifications used (
README.md)
Submit a new idiom to the repository
- Review CONTRIBUTING.md to understand the submission requirements and format standards (
CONTRIBUTING.md) - Create your idiom comparison file following the established pattern in the appropriate code/ subdirectory (
code/general/loop-vs-while-true.rb) - Include a detailed README.md entry with benchmark numbers, use-case explanation, and links to real-world examples (
README.md) - Verify the benchmarks pass CI/CD validation through the GitHub Actions workflow (
.github/workflows/benchmarks.yml)
🔧Why these technologies
- Benchmark.ips (Ruby) — Built-in Ruby benchmarking gem measures iterations per second, the standard metric for Ruby performance comparisons, directly relevant to the idioms being tested
- GitHub Actions (CI/CD) — Automates benchmark execution on every commit, ensures consistency across runs, and transparently reports performance changes to contributors
- Rake (Task Runner) — Simple Ruby task orchestration for managing benchmark execution, output generation, and result aggregation across the entire codebase
- Markdown Documentation — Lightweight, version-controllable format for documenting idioms, results, and real-world commit links; GitHub renders it directly in the repo
⚖️Trade-offs already made
-
Single-threaded Benchmark.ips execution
- Why: Ensures reproducible results by eliminating concurrency noise; idiom performance is relative, not absolute
- Consequence: Benchmarks run sequentially and may take several minutes; provides stable, comparable metrics across different machines
-
Idioms organized by Ruby construct type (Array, String, Hash, etc.)
- Why: Clear mental model matching Ruby's standard library; easy to navigate for users looking for specific patterns
- Consequence: Some idioms appear in multiple categories; duplication accepted in favor of discoverability
-
No automated performance regression gates in CI
- Why: Results vary by Ruby version and machine specs; maintainers review results manually to avoid false positives
- Consequence: Slower feedback loop; requires human judgment to determine if a regression is meaningful
-
Emphasis on real-world commit links and examples
- Why: Proves idioms have tangible impact in production code; builds credibility with developers
- Consequence: Requires additional research and curation effort per idiom; motivates careful, vetted submissions
🚫Non-goals (don't propose these)
- Does not provide automated code refactoring or linting tools—purely educational benchmarking
- Does not guarantee idioms are universally faster across all Ruby versions or platforms—results are specific to tested environment
- Does not replace profiling and benchmarking in production code—idiom speedups depend on context and workload
- Does not provide performance tuning beyond idiom-level micro-optimizations—does not address algorithmic or architectural improvements
- Not a Ruby runtime or compiler project—purely a knowledge-base and benchmarking reference
🪤Traps & gotchas
No hidden traps. The repo is deliberately simple: each .rb file is self-contained and can be run independently with ruby code/.... Results are platform-specific (macOS M4 Pro mentioned in README), so your benchmarks on Linux or Intel may differ. The disclaimer 'does not mean you can always blindly replace one with another' is critical—context matters (e.g., gsub vs tr performance depends on pattern complexity).
🏗️Architecture
💡Concepts to learn
- Microbenchmarking with iterations-per-second (ips) — Understanding how benchmark-ips stabilizes variance and measures throughput helps learners correctly interpret the results and avoid false conclusions from noisy benchmarks
- Ruby method call overhead vs C-level optimizations — Many idiom wins (attr_accessor, flat_map) come from native C implementations vs Ruby-level method chains; recognizing this pattern helps learners predict which refactors will help
- Garbage collection pressure and object allocation — Some optimizations (e.g., merge vs merge!) win by reducing intermediate object creation; understanding GC impact on throughput is crucial for long-running processes
- Symbol vs String performance tradeoffs — Multiple idioms rely on symbol interning and hash lookup semantics; learners must grasp why symbols are faster in certain contexts (hash keys) but not others
- Early return optimization (Enumerable#detect vs #select#first) — Understanding that lazy evaluation and short-circuit patterns avoid unnecessary iterations is foundational for writing efficient collection processing code
- Splat operator behavior and method signature optimization — The idiom 'array argument vs splat arguments' reveals how Ruby's method dispatch and argument unpacking impact performance; relevant for API design
- Lazy evaluation and Enumerator chains — Some idioms benefit from Enumerator#lazy to avoid materializing intermediate arrays; learners should understand when lazy evaluation saves memory and CPU
🔗Related repos
DamirSvrtan/fasterer— Static analyzer linter that checks your Ruby code against idioms documented in fast-ruby, automating detection of slow patterns in CI/CDruby/ruby— The official Ruby interpreter repository; understanding MRI implementation details explains why certain idioms are faster (e.g., C-level optimizations in attr_accessor)evanphx/benchmark-ips— The underlying gem (v2.0+) used in every benchmark file for stable, reproducible performance measurementssferik/writing-fast-ruby— Original inspiration: Erik Michaels-Ober's 'Writing Fast Ruby' talk slides and video that this repo documents as executable benchmarkspresidentbeef/brakeman— Complementary Rails security scanner; many of fast-ruby's idioms apply to Rails-specific code patterns (e.g., hash merging in controllers)
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add benchmark results comparison matrix to README.md
The repo has 50+ benchmark files in code/ directories but README.md doesn't display aggregated results or a comparison table. Contributors could extract benchmark outputs from benchmarks.yml workflow and create a structured results matrix showing performance improvements for each idiom category (array, enumerable, hash, string, etc.). This makes the repo's value immediately visible without running benchmarks locally.
- [ ] Parse outputs from .github/workflows/benchmarks.yml to understand current benchmark execution
- [ ] Create a results aggregation script that runs all benchmarks in code/ subdirectories and formats results
- [ ] Add a 'Benchmark Results' section to README.md with a markdown table showing idiom, faster approach, slower approach, and % improvement
- [ ] Update benchmarks.yml workflow to auto-generate and commit results to a RESULTS.md or similar
Add missing benchmark files for nil/falsy checks and string interpolation
The repo documents many Ruby idioms but gaps exist in common patterns. Looking at code/general/ and code/string/, there are no benchmarks for: (1) nil checks (obj.nil? vs obj == nil vs !obj), (2) string interpolation vs concatenation edge cases, (3) empty? vs size == 0 for strings/arrays. These are frequently debated idioms that would provide high value.
- [ ] Create code/general/nil-check-methods.rb benchmarking .nil? vs == nil vs falsy checks
- [ ] Create code/string/interpolation-vs-concat-vs-format.rb comparing different string building methods
- [ ] Create code/enumerable/empty-vs-size-vs-length-vs-any.rb for collection emptiness checks
- [ ] Add corresponding examples to README.md in their respective sections with performance conclusions
Add Ruby version compatibility notes to code examples
Several benchmarks test idioms with different performance characteristics across Ruby versions (e.g., dig added in 2.3.0, double-splat in 2.5.0, pattern matching in 2.7.0). Currently code/hash/dig-vs-[]-vs-fetch.rb and code/hash/merge-vs-double-splat-operator.rb lack version documentation. Adding version guards and comments helps contributors understand minimum Ruby versions needed and explains why some idioms only became viable recently.
- [ ] Audit all 50+ benchmark files and identify which require specific Ruby versions
- [ ] Add YAML frontmatter or comments to each code/*.rb file with 'min_ruby_version: X.Y.Z' and description of version-specific behavior
- [ ] Create a doc/RUBY_VERSIONS.md listing all benchmarks by minimum Ruby version requirement
- [ ] Update Gemfile or Rakefile to validate/skip benchmarks based on current Ruby version
🌿Good first issues
- Add benchmarks for Ruby 4.1+ string methods (e.g., String#delete vs String#tr, String#scan performance). Create code/string/delete-vs-tr.rb following the template and update README.md with results.
- Expand code/time/ and code/range/ directories which are minimally represented compared to array/enumerable/hash. Add 3–4 idiom comparisons (e.g., Range#cover? vs Range#include?, Time#now vs Time.current) with benchmarks.
- Document the relationship between idiom performance and Ruby version in README.md with a version-compatibility matrix. Add a section showing which optimizations regressed or improved from Ruby 3.x to 4.0.0 based on existing benchmark results.
⭐Top contributors
Click to expand
Top contributors
- @Arcovion — 16 commits
- @etagwerker — 11 commits
- @bdewater — 9 commits
- @styd — 6 commits
- @wasaylor — 4 commits
📝Recent commits
Click to expand
Recent commits
2342b8a— Update benchmarks to Ruby 4.0.0 on a recent MacBook Pro. (#234) (kewlar)36296ef— Fixes the 'planets align' condition of select.last vs reverse.detect (#233) (etagwerker)be7e578— Fix Ubuntu version (#232) (JuanVqz)2193aba— CI: add ruby-3.2 to matrix (#224) (ishigo974)8250040— link in readme is not relevant anymore (#231) (TrueJacobG)b9abe22— Update the yield benchmark for CRuby 2.5 changes (#141) (havenwood)7797b38— Fix links (#226) (ydakuka)a9e12bc— README.md: avoid redirections on Github repository links from previous owner to current owner (#222) (ishigo974)6a45bdf— Run old rubies with Ubuntu 20 in CI (#221) (arielj)1198345— compare gsub vs tr vs delete to remove character from string (#121) (mojavelinux)
🔒Security observations
This repository is a Ruby benchmarking and idiom documentation project with minimal security risks. No critical vulnerabilities were identified. The codebase consists primarily of educational code examples for performance testing rather than production code, secrets management, or external system interactions. The project has no dependency file (Gemfile content not provided for analysis), no hardcoded credentials detected, and no injection vectors typical of data-processing applications. The GitHub Actions workflow for benchmarks follows standard CI/CD practices. The only minor consideration is ensuring benchmark code samples are reviewed before publication, but this is a low-risk educational resource.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.