Martin Jansson wrote:
> I recently started to learn Ruby. I thought that the obviously flawed
> Random
> benchmark at http://shootout.alioth.debian.org would make a good first
> project.
>
> I need some help with profiling as my system is a lot different from the
> shootout setup. My system is a iBook G4 with Mac OS 10.3 and Ruby 1.8. They
> use Linux on AMD with Ruby 1.9.
>
> The original implementation have two eyecatching flaws:
>   1) It use Floats instead of Fixnum
>   2) It uses a really costly way to get the first program parameter.
>
> After I corrected these two misstakes it used 30% less time and
> considerably less memory (at least half as much, hard to measure).
>
> Then I started from scratch and wrote my own version, doing a lot of
> experimentation. This is the result:
>
> # Code start
>
> module Kernel
>    $srandom = 42
>    def random(max)
>      (max * ($srandom = ($srandom * 3877 + 29573) % 139968)).quo(139968)
>    end
> end
>
> ($*.first.to_i-1).times do
>    random(100)
> end
>
> printf "%.9f\n", random(100)
>
> # Code end
>
>
> The most important qualities is (in order of saved time):
> * Use Fixnum for integer arithmetics. Much faster and with better
> precision.
> * Use ARGV.first instead of ARGV.shift to get first parameter
> * Use literals instead of constants. Ruby constants is no real constants,
>    they are global variables with A LOT of overhead. The specification
>    C-program use literals. An alternative would be to use
>    local variables.


"Each program should use symbolic constants (or whatever is closest) to
define the A, C, and M constants in the algorithm, not literal
constants."

http://shootout.alioth.debian.org/benchmark.php?test=random&lang=all&sort=fullcpu#about


> * Use $* instead of ARGV. Sigh. Ruby constants are really, reeeally
> slooooow.
> * Use times as iterator. As do the original solution.
> * Use a global variable to hold the seed. As do the original solution.
>    I can't find a sane way to keep the seed between method calls without
>    consuming a lot of precious time.
> * Wraped the function in module Kernel. For some odd reason this makes the
>    program somewhat faster. I really don't like it, but...
>
> I've also tried a nice Simula flavoured version an, not so nice,
> "oo"-version and a lot of really wacky versions.
> They are a lot faster then the original code, but slower then the above
> version.