Expedite initialize.
[framework/uifw/expedite.git] / src / bin / expedite-cmp
1 #!/usr/bin/env python
2
3 import sys
4 import os
5 import os.path
6 import csv
7 from optparse import OptionParser
8
9 fmttext = '%(value)7.2f (%(percentual)+6.1f%%)'
10 fmthtml = '%(value)7.2f <span style="color: #666; width: 55pt; display: inline-block; text-align: right; text-shadow: #999 1px 1px 3px;">(%(percentual)+0.1f%%)</span>'
11
12
13 parser = OptionParser(usage="%prog [options] <reference> <file2> .. <fileN>",
14                       description="""\
15 Generate reports comparing two or more outputs of expedite.
16
17 Just run expedite and save output to a file and then feed them to this
18 program. The first file is used as base for comparison and other files
19 will print relative improvements.
20 """)
21 parser.add_option("-e", "--accepted-error",
22                   help=("maximum error to accept as percentage 0.0-1.0. "
23                         "[default=%default]"),
24                   action="store", type="float", default=0.05)
25 parser.add_option("-r", "--report",
26                   help=("kind of report to use. One of text or html. "
27                         "[default=%default]"),
28                   action="store", type="choice", default="text",
29                   choices=["text", "html"])
30 parser.add_option("-F", "--format",
31                   help=("format to use as python format string, "
32                         "valid keys are: value and percentual. "
33                         "[defaults: html=\"%s\", text=\"%s\"]" %
34                         (fmthtml, fmttext)),
35                   action="store", type="str", default=None)
36 parser.add_option("-C", "--no-color", dest="color",
37                   help="do not use color in reports.",
38                   action="store_false", default=True)
39
40 options, files = parser.parse_args()
41 if len(files) < 2:
42     raise SystemExit("need at least 2 files to compare")
43
44 if options.format is None:
45     if options.report == "html":
46         options.format = fmthtml
47     else:
48         options.format = fmttext
49
50 ref_f = files[0]
51 others_f = files[1:]
52
53 max_test_name = 0
54 data = {}
55 tests = []
56 for f in files:
57     d = data[f] = {}
58     for row in csv.reader(open(f)):
59         t = row[1].strip()
60         if f == ref_f:
61             tests.append(t)
62         d[t] = float(row[0])
63         max_test_name = max(len(t), max_test_name)
64
65 def report_text():
66     test_name_fmt = "%%%ds:" % max_test_name
67
68     fmtsize = len(options.format % {"value": 12345.67, "percentual": 1234.56})
69     hdrfmt = "%%%d.%ds" % (fmtsize, fmtsize)
70
71     print test_name_fmt % "\\",
72     print "%7.7s" % (files[0][-7:],),
73     for f in files[1:]:
74         n, e = os.path.splitext(f)
75         print hdrfmt % n[-fmtsize:],
76     print
77
78     if options.color and os.environ.get("TERM", "") in (
79         "xterm", "xterm-color", "rxvt", "rxvt-unicode", "screen",
80         "Eterm", "aterm", "gnome", "interix"):
81         color_good = "\033[1;32m"
82         color_bad = "\033[1;31m"
83         color_equal = "\033[1;30m"
84         color_reset = "\033[0m"
85     else:
86         color_good = ""
87         color_bad = ""
88         color_equal = ""
89         color_reset = ""
90
91
92     def print_row(test):
93         print test_name_fmt % test,
94         ref_val = data[ref_f][test]
95         print "%7.2f" % ref_val,
96         for f in others_f:
97             try:
98                 val = data[f][test]
99             except KeyError:
100                 print "-?????-",
101                 continue
102
103             percent = (val - ref_val) / ref_val
104             if percent < -options.accepted_error:
105                 c = color_bad
106             elif percent > options.accepted_error:
107                 c = color_good
108             else:
109                 c = color_equal
110
111             fmt = options.format % {"value": val, "percentual": percent * 100}
112             if len(fmt) < fmtsize:
113                 fmt = hdrfmt % fmt
114             print "%s%s%s" % (c, fmt, color_reset),
115
116         print
117
118     for t in tests:
119         print_row(t)
120
121
122 def report_html():
123     import time
124
125     fnames = [os.path.basename(f) for f in files]
126     print """\
127 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
128   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
129
130 <html xmlns="http://www.w3.org/1999/xhtml">
131   <head>
132     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
133     <title>expedite comparison sheet: %(files)s</title>
134   </head>
135   <style type="text/css">
136     table
137     {
138        border: 1px solid black;
139        border-collapse: collapse;
140     }
141     thead
142     {
143        border-bottom: 1px solid black;
144     }
145     tr.overall-results
146     {
147        border-top: 1px solid black;
148        font-weight: bold;
149     }
150     td.value, td.value-reference, td.value-missing, td.value-good, td.value-bad, td.value-equal
151     {
152        font-family: courier, monospaced;
153        font-size: 10pt;
154        text-align: right;
155        border-left: 1px solid black;
156        border-bottom: 1px dashed #ccc;
157     }
158     td.test-name, thead tr td { text-align: right; }\
159 """
160     if options.color:
161         print """\
162     td.value-good { background-color: #aaffaa; }
163     td.value-bad { background-color: #ffaaaa; }
164     td.value-missing { background-color: #ffffaa; }
165     td.test-name, thead tr td
166     {
167        font-weight: bold;
168        background-color: #d9d9d9;
169        border-bottom: 1px dashed #ccc;
170     }
171 """
172
173     print """
174   </style>
175   <body>
176      <p>Comparison sheet for %(files)s, created at %(date)s.</p>
177      <table>
178        <thead>
179          <tr>
180            <td>\\</td>\
181 """ % {"files": ", ".join(fnames),
182        "date": time.asctime(),
183        }
184
185     for f in fnames:
186         print """\
187            <td>%s</td>\
188 """ % f
189     print """\
190          </tr>
191        </thead>
192        <tbody>\
193 """
194
195     def print_row(test):
196         ref_val = data[ref_f][test]
197         if "EVAS SPEED" in test.upper():
198             extra_cls = ' class="overall-results"'
199         else:
200             extra_cls = ""
201
202         print """\
203          <tr%s>
204            <td class="test-name">%s</td>
205            <td class="value-reference">%7.2f</td>\
206 """ % (extra_cls, test, ref_val)
207
208         for f in others_f:
209             try:
210                 val = data[f][test]
211             except KeyError:
212                 print """\
213            <td class="value-missing">-?????-</td>\
214 """
215                 continue
216
217             percent = (val - ref_val) / ref_val
218             if percent < -options.accepted_error:
219                 c = 'bad'
220             elif percent > options.accepted_error:
221                 c = 'good'
222             else:
223                 c = 'equal'
224
225             v = options.format % {"value": val, "percentual": percent * 100}
226
227             print """\
228            <td class="value-%s">%s</td>\
229 """ % (c, v)
230
231         print """\
232          </tr>\
233 """
234
235     for t in tests:
236         print_row(t)
237
238     print """\
239        </tbody>
240      </table>
241   </body>
242 </html>
243 """
244
245 if options.report == "text":
246     report_text()
247 elif options.report == "html":
248     report_html()