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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
#!/usr/bin/env ruby
#
# ruby program to generate a performance report in PDF/png over git revisions, based on work
# originally done for gegl by pippin@gimp.org, the original program is in the public domain.
require 'cairo'
def cairo_surface(w,h)
surface = Cairo::PDFSurface.new("report.pdf", w,h)
cr = Cairo::Context.new(surface)
yield(cr)
end
class Database
def initialize()
@vals = Hash.new
@runs = Array.new
@colors = [
[0,1,0, 0.8],
[0,1,1, 0.8],
[1,0,0, 0.8],
[1,0,1, 0.8],
[1,1,0, 0.8],
#[0.5,0.5,0.5,0.8],
# gray doesnt have sufficient contrast against background
[0.5,0.5,1, 0.8],
[0.5,1,0.5, 0.8],
[0.5,1,1, 0.8],
[1,0.5,0.5, 0.8],
[1,0.5,1, 0.8],
[1,1,0.5, 0.8],
[1,1,1, 0.8],
]
@width = 1800
@height = 500
@marginlx = 10
@marginrx = 180
@rgap = 40
@marginy = 10
end
def val_max(key)
max=0
@runs.each { |run|
val = @vals[key][run]
if val and val > max
max = val
end
}
max
end
def val_min(key)
min=9999990
@runs.each { |run|
val = @vals[key][run]
min = val if val and val < min
}
#min
0 # this shows the relative noise in measurements better
end
def add_run(run)
@runs = @runs + [run]
end
def add_entry(run, name, val)
if !@vals[name]
@vals[name]=Hash.new
end
# check if there is an existing value,
# and perhaps have different behaviors
# associated with
@vals[name][run] = val.to_f
end
def drawbg cr
cr.set_source_rgba(0.2, 0.2, 0.2, 1)
cr.paint
i=0
@runs.each { |run|
if i % 2 == 1
cr.move_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, 0 * (@height - @marginy*2) + @marginy
cr.line_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, 1.0 * (@height - @marginy*2) + @marginy
cr.rel_line_to(1.0 / @runs.length * (@width - @marginlx-@marginrx), 0)
cr.rel_line_to(0, -(@height - @marginy*2))
cr.set_source_rgba([0.25,0.25,0.25,1])
cr.fill
end
i+=1
}
end
def drawtext cr
i = 0
@runs.each { |run|
y = i * 10 + 20
while y > @height - @marginy
y = y - @height + @marginy + 10
end
cr.move_to 1.0 * i / @runs.length * (@width - @marginlx-@marginrx) + @marginlx, y
cr.set_source_rgba(0.6,0.6,0.6,1)
cr.show_text(run[0..6])
i+=1
}
end
def draw_limits cr, key
cr.move_to @width - @marginrx + @rgap, 20
cr.set_source_rgba(1.0, 1.0, 1.0, 1.0)
cr.show_text(" #{val_max(key)} ")
cr.move_to @width - @marginrx + @rgap, @height - @marginy
cr.show_text(" #{val_min(key)} ")
end
def draw_val cr, key, valno
min = val_min(key)
max = val_max(key)
cr.set_source_rgba(@colors[valno])
cr.move_to(@width - @marginrx + @rgap, valno * 14 + @marginy + 20)
cr.show_text(key)
cr.line_width = 2
cr.new_path
i = 0
@runs.each { |run|
val = @vals[key][run]
if val
cr.line_to 1.0 * (i+0.5) / @runs.length * (@width - @marginlx-@marginrx) + @marginlx,
(1.0 - ((val-min) * 1.0 / (max - min))) * (@height - @marginy*2) + @marginy
end
i = i + 1
}
cr.stroke
end
def create_report
cairo_surface(@width, @height) { |cr|
drawbg cr
valno = 0
@vals.each { |key, value|
draw_val cr, key, valno
valno += 1
}
drawtext cr
cr.target.write_to_png("report.png")
valno = 0
@vals.each { |key, value|
cr.show_page
drawbg cr
draw_val cr, key, valno
drawtext cr
draw_limits cr, key
valno += 1
}
}
end
end
generator = Database.new
items = File.open('jobs').each { |rev|
rev.strip!
generator.add_run(rev)
filename = "reports/" + rev;
if File.exist?(filename)
File.open(filename).each { |line|
if line =~ /^@ (.*):(.*)/
generator.add_entry(rev, $1, $2)
end
}
end
}
generator.create_report
|