summaryrefslogtreecommitdiff
path: root/benchmark/so_mandelbrot.yml
blob: daa58a0133f2e02c9c1e11cd839adeee2f5eab23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
prelude: |
  #  The Computer Language Benchmarks Game
  #  http://shootout.alioth.debian.org/
benchmark:
  so_mandelbrot: |
    #
    #  contributed by Karl von Laudermann
    #  modified by Jeremy Echols

    size = 600 # ARGV[0].to_i

    puts "P4\n#{size} #{size}"

    ITER = 49                           # Iterations - 1 for easy for..in looping
    LIMIT_SQUARED = 4.0                 # Presquared limit

    byte_acc = 0
    bit_num = 0

    count_size = size - 1               # Precomputed size for easy for..in looping

    # For..in loops are faster than .upto, .downto, .times, etc.
    for y in 0..count_size
      for x in 0..count_size
        zr = 0.0
        zi = 0.0
        cr = (2.0*x/size)-1.5
        ci = (2.0*y/size)-1.0
        escape = false

        # To make use of the for..in code, we use a dummy variable,
        # like one would in C
        for dummy in 0..ITER
          tr = zr*zr - zi*zi + cr
          ti = 2*zr*zi + ci
          zr, zi = tr, ti

          if (zr*zr+zi*zi) > LIMIT_SQUARED
            escape = true
            break
          end
        end

        byte_acc = (byte_acc << 1) | (escape ? 0b0 : 0b1)
        bit_num += 1

        # Code is very similar for these cases, but using separate blocks
        # ensures we skip the shifting when it's unnecessary, which is most cases.
        if (bit_num == 8)
          print byte_acc.chr
          byte_acc = 0
          bit_num = 0
        elsif (x == count_size)
          byte_acc <<= (8 - bit_num)
          print byte_acc.chr
          byte_acc = 0
          bit_num = 0
        end
      end
    end
loop_count: 1