Bash relies highly on external commands which make it having a lot of overheads; it's the language of the command line, not a proper programming language; it'll work well when most of time is spend by external binaries.
time ruby bench.rb > /dev/null; time bash bench.sh > /dev/null
There's no comparison. ruby is magnitudes faster than bash
The scripts --
declare -i i
while test $i -le 999999
echo hello world
i = 0
while (i <= 999999)
puts "hello world"
i = i + 1
In the bash binary there's frequent execution of 2 independent binaries -- test and echo which makes it slow.