Startling new proof that Ruby sucks at scripting!
Scripting languages should launch quickly, run at acceptable speeds, then exit quickly. Consider this script:
#!/usr/bin/env zsh
cat << SNOBOL4 > bogobench.sno
OUTPUT = "Hello, world!"
END
SNOBOL4
cat << REXX > bogobench.rexx
say "Hello, world!"
REXX
cat << AWK > bogobench.awk
BEGIN {
print "Hello, world!\n"
}
AWK
cat << RUBY > bogobench.rb
puts "Hello, world!"
RUBY
cat << LUA > bogobench.lua
print "Hello, world!"
LUA
cat << PROLOG > bogobench.pl
main :- write('Hello, world!'), nl.
PROLOG
cat << ERLANG > bogobench.escript
main(_) -> io:format("Hello, world!~n").
ERLANG
cat << JAVA > bogobench.java
public class bogobench
{
public static void main(String[] args)
{
System.out.println("Hello, world!");
}
}
JAVA
javac bogobench.java
/usr/bin/time -p ./bogoloop awk -f bogobench.awk
/usr/bin/time -p ./bogoloop rexx bogobench.rexx
/usr/bin/time -p ./bogoloop snobol4 -b bogobench.sno
/usr/bin/time -p ./bogoloop lua bogobench.lua
/usr/bin/time -p ./bogoloop swipl -q -t main -f bogobench.pl
/usr/bin/time -p ./bogoloop java bogobench
/usr/bin/time -p ./bogoloop escript bogobench.escript
/usr/bin/time -p ./bogoloop ruby bogobench.rb
rm bogobench.*
It’s simple enough: it generates the test scripts using here-documents. In the case of Java, placed as an example of a well-known start-up time hog, the test script is then compiled. The script is then run 100 times in a tight loop using this script:
#!/usr/bin/env zsh
max_iter=100
a=0
echo "Running '$*' $max_iter times…"
while [ $a -lt "$max_iter" ]
do
a=$((a + 1))
$* > /dev/null
done
echo "…done."
Very straightforward. And, of course, we’d expect a few things:
- Execution time should be negligible. All that’s being done, after all, is outputting a string, something scripting languages should excel at.
- SWI-Prolog and Erlang both should be pretty damned slow, given that they’re massive languages with massive run-time systems behind them (and in both cases the “scripting” is mostly an afterthought).
- Java, with its notorious JVM load time, should be incredibly slow.
Results
The two numbers that are meaningful in the time output are the user and sys values. Take a look at the raw results:
./bogobench
Running 'awk -f bogobench.awk' 100 times…
…done.
real 0.66
user 0.03
sys 0.03
Running 'rexx bogobench.rexx' 100 times…
…done.
real 0.36
user 0.00
sys 0.05
Running 'snobol4 -b bogobench.sno' 100 times…
…done.
real 0.52
user 0.00
sys 0.05
Running 'lua bogobench.lua' 100 times…
…done.
real 0.28
user 0.01
sys 0.03
Running 'swipl -q -t main -f bogobench.pl' 100 times…
…done.
real 2.40
user 1.32
sys 0.70
Running 'java bogobench' 100 times…
…done.
real 12.03
user 8.75
sys 2.00
Running 'escript bogobench.escript' 100 times…
…done.
real 18.89
user 13.77
sys 2.46
Running 'ruby bogobench.rb' 100 times…
…done.
real 49.53
user 43.10
sys 3.74
Guh… what?!
Results
In EVERY SINGLE METRIC Ruby came in slower—often by two orders of magnitude!—than EVERY OTHER LANGUAGE. Let’s consolidate the results, adding together user and system time:
| language | time(s) |
|---|---|
| lua | 0.04 |
| rexx | 0.05 |
| snobol4 | 0.05 |
| awk | 0.06 |
| prolog | 2.02 |
| java | 10.75 |
| erlang | 16.23 |
| ruby | 46.84 |
Consider what this means. Lua is a better scripting language than Ruby in that it is just the fastest of the bunch while being easily as powerful. Rexx, a language made in the ‘70s on ancient, creaking mainframes is a better scripting language than Ruby in that, while it may be a little bit less powerful, it sure as Hell is faster at loading. (And how much power do you actually need for scripting?) Awk, too, another language from the ‘70s, is more than powerful enough for most scripting needs, and well within acceptable load speed parameters.
More embarrassingly, Prolog, a language not intended for scripting, and, further, an implementation that’s not noted for being quick, is almost acceptable as a scripting language, coming in a good twenty times as fast at loading as Ruby. Erlang, too, even though it’s a painfully slow startup, is over three times as fast as Ruby at loading.
Even Java, a language not intended for scripting and infamously slow at loading is almost five times as fast as Ruby (and about 1.6 times as fast as Erlang).
Ruby, it turns out, is worse as a scripting language than three scripting languages from as far back as the ‘60s, not to mention three languages that aren’t even really intended for scripting.
Versions
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
REXX-Regina_3.7 5.00 14 Oct 2012
CSNOBOL4 version 1.4.1 (January 19, 2012)
GNU Awk 3.1.7
java version "1.7.0_17" Java(TM) SE Runtime Environment (build 1.7.0_17-b02) Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
rubinius 2.0.0.rc1 (1.8.7 release yyyy-mm-dd JI) [x86_64-unknown-linux-gnu]
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:true]