Benchmark Results: Ruby 4.0.1 vs Python 3.14.3 vs Perl 5.42.0
Link to heading
- Ruby: 4.0.1 with YJIT/ZJIT enabled
- Python: 3.14.3
- Perl: 5.42.0
- 100,000 iterations for most tests
- 10,000 iterations for array tests
| Test |
Ruby 4.0.1 |
Python 3.14.3 |
Perl 5.42.0 |
Winner |
| rational |
2.69s |
5.47s |
(error) |
Ruby |
| loop |
0.0018s |
0.0127s |
0.0041s |
Ruby |
| string |
0.41s |
0.11s |
0.005s |
Python |
| array |
4.73s |
3.88s |
5.40s |
Python |
| Total |
7.84s |
9.47s |
5.41s* |
Ruby |
*Perl rational test had errors
With --zjit flag:
| Test |
Ruby (no ZJIT) |
Ruby (–zjit) |
Improvement |
| rational |
2.69s |
2.70s |
-0.3% |
| loop |
0.0018s |
0.0017s |
6% |
| string |
0.41s |
0.40s |
2% |
| array |
4.73s |
4.01s |
15% |
| Total |
7.84s |
7.11s |
9% |
Conclusion: ZJIT provides ~9% overall improvement, with biggest gains in array operations (15%).
Test 2: String Operations (Ruby YJIT vs Python)
Link to heading
Ruby strings are mutable by default. Using the wrong concatenation method makes a huge difference:
| Method |
Time (100k iterations) |
str += "x" |
0.47s |
str << "x" |
0.009s |
Using << is 98% faster than +=!
Updated String Benchmark (using <<)
Link to heading
| Test |
Ruby 4 + YJIT (<<) |
Python 3.14.3 |
Winner |
| concat |
0.003s |
0.013s |
Ruby |
| interpolation |
0.019s |
0.023s |
Ruby |
| gsub/replace |
0.005s |
0.0016s |
Python |
| split/join |
0.008s |
0.003s |
Python |
| Total |
0.036s |
0.04s |
Ruby |
Test 3: Ruby String Optimizations (gsub vs tr, split vs index/slice)
Link to heading
| Operation |
Standard Method |
Optimized Method |
Potential Gain |
| Replace characters |
gsub("o", "0") |
tr("o", "0") |
500-1000% |
| Extract first word |
"a,b".split(",").first |
"a,b".index(",") then slice |
200-400% |
Results with Optimized Methods
Link to heading
| Test |
Ruby 4 + YJIT |
Python 3.14.3 |
Winner |
| concat |
0.010s |
0.012s |
Ruby |
| interpolation |
0.015s |
0.023s |
Ruby |
| gsub |
0.0076s |
0.0014s |
Python |
| tr |
0.0033s |
0.0028s |
Python |
| split_join |
0.0104s |
0.0025s |
Python |
| index_slice |
0.0037s |
0.0021s |
Python |
| partition |
0.0033s |
0.0024s |
Python |
| Total |
0.062s |
0.046s |
Python |
# ✓ FAST: Use << for concatenation
str = "".dup
str << "hello" << " world"
# ✓ FAST: Use tr for simple character replacement
"hello".tr("el", "01") # => "h0110"
# ✓ FAST: Use index/slice instead of split
s = "a,b,c,d,e"
pos = s.index(',')
first = s[0...pos]
# ✓ FAST: Use partition for first delimiter
first, sep, rest = "a,b,c".partition(',') # => ["a", ",", "b,c"]
# ✗ SLOW: Avoid these
str += "x" # use << instead
"str".gsub("a", "b") # use tr for single char
"str".split(",") # use index/slice if only partial needed
| Category |
Winner |
Notes |
| Loops/Numeric |
Ruby 4 + YJIT |
7x faster than Python |
| String concat |
Ruby 4 + YJIT |
4.5x faster (with <<) |
| String manipulation |
Python |
2-3x faster for gsub/split |
| Rational math |
Ruby 4 + YJIT |
2x faster than Python |
- Ruby 4 with YJIT/ZJIT is extremely fast - especially for loops (7x faster than Python)
- Use
<< for string concatenation - 98% faster than +=
- Ruby is competitive with Python - especially when using proper string methods
- Python still leads in text processing - but Ruby catches up with correct techniques
Recommendation for Ruby Developers
Link to heading
# DO: Use << for string building
str = "".dup
str << "hello"
str << " world"
# DON'T: Use += for repeated concatenation
str = ""
str += "hello" # Much slower!