]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/perf/perldriver/Output.pm
ICU-531.30.tar.gz
[apple/icu.git] / icuSources / test / perf / perldriver / Output.pm
1 #!/usr/local/bin/perl
2
3 # ********************************************************************
4 # * COPYRIGHT:
5 # * Copyright (c) 2002, International Business Machines Corporation and
6 # * others. All Rights Reserved.
7 # ********************************************************************
8
9
10 use strict;
11
12 use Dataset;
13
14 my $TABLEATTR = 'BORDER="1" CELLPADDING="4" CELLSPACING="0"';
15 my $outType = "HTML";
16 my $html = "noName";
17 my $inTable;
18 my @headers;
19 my @timetypes = ("mean per op", "error per op", "events", "per event");
20 my %raw;
21 my $current = "";
22 my $exp = 0;
23 my $mult = 1e9; #use nanoseconds
24 my $perc = 100; #for percent
25 my $printEvents = 0;
26 my $legend = "<a name=\"Legend\">\n<h2>Table legend</h2></a><ul>";
27 my $legendDone = 0;
28 my %options;
29 my $operationIs = "operation";
30 my $eventIs = "event";
31
32 sub startTest {
33 $current = shift;
34 $exp = 0;
35 outputData($current);
36 }
37
38 sub printLeg {
39 if(!$legendDone) {
40 my $message;
41 foreach $message (@_) {
42 $legend .= "<li>".$message."</li>\n";
43 }
44 }
45 }
46
47 sub outputDist {
48 my $value = shift;
49 my $percent = shift;
50 my $mean = $value->getMean;
51 my $error = $value->getError;
52 print HTML "<td class=\"";
53 if($mean > 0) {
54 print HTML "value";
55 } else {
56 print HTML "worse";
57 }
58 print HTML "\">";
59 if($percent) {
60 print HTML formatPercent(2, $mean);
61 } else {
62 print HTML formatNumber(2, $mult, $mean);
63 }
64 print HTML "</td>\n";
65 print HTML "<td class=\"";
66 if((($error*$mult < 10)&&!$percent) || (($error<10)&&$percent)) {
67 print HTML "error";
68 } else {
69 print HTML "errorLarge";
70 }
71 print HTML "\">&plusmn;";
72 if($percent) {
73 print HTML formatPercent(2, $error);
74 } else {
75 print HTML formatNumber(2, $mult, $error);
76 }
77 print HTML "</td>\n";
78 }
79
80 sub outputValue {
81 my $value = shift;
82 print HTML "<td class=\"sepvalue\">";
83 print HTML $value;
84 #print HTML formatNumber(2, 1, $value);
85 print HTML "</td>\n";
86 }
87
88 sub startTable {
89 #my $printEvents = shift;
90 $inTable = 1;
91 my $i;
92 print HTML "<table $TABLEATTR>\n";
93 print HTML "<tbody>\n";
94 if($#headers >= 0) {
95 my ($header, $i);
96 print HTML "<tr>\n";
97 print HTML "<th rowspan=\"2\" class=\"testNameHeader\"><a href=\"#TestName\">Test Name</a></th>\n";
98 print HTML "<th rowspan=\"2\" class=\"testNameHeader\"><a href=\"#Ops\">Ops</a></th>\n";
99 printLeg("<a name=\"Test Name\">TestName</a> - name of the test as set by the test writer\n", "<a name=\"Ops\">Ops</a> - number of ".$operationIs."s per iteration\n");
100 if(!$printEvents) {
101 print HTML "<th colspan=".((4*($#headers+1))-2)." class=\"sourceType\">Per Operation</th>\n";
102 } else {
103 print HTML "<th colspan=".((2*($#headers+1))-2)." class=\"sourceType\">Per Operation</th>\n";
104 print HTML "<th colspan=".((5*($#headers+1))-2)." class=\"sourceType\">Per Event</th>\n";
105 }
106 print HTML "</tr>\n<tr>\n";
107 if(!$printEvents) {
108 foreach $header (@headers) {
109 print HTML "<th class=\"source\" colspan=2><a href=\"#meanop_$header\">$header<br>/op</a></th>\n";
110 printLeg("<a name=\"meanop_$header\">$header /op</a> - mean time and error for $header per $operationIs");
111 }
112 }
113 for $i (1 .. $#headers) {
114 print HTML "<th class=\"source\" colspan=2><a href=\"#mean_op_$i\">ratio $i<br>/op</a></th>\n";
115 printLeg("<a name=\"mean_op_$i\">ratio $i /op</a> - ratio and error of per $operationIs time, calculated as: (($headers[0] - $headers[$i])/$headers[$i])*100%, mean value");
116 }
117 if($printEvents) {
118 foreach $header (@headers) {
119 print HTML "<th class=\"source\"><a href=\"#events_$header\">$header<br>events</a></th>\n";
120 printLeg("<a name=\"events_$header\">$header events</a> - number of ".$eventIs."s for $header per iteration");
121 }
122 foreach $header (@headers) {
123 print HTML "<th class=\"source\" colspan=2><a href=\"#mean_ev_$header\">$header<br>/ev</a></th>\n";
124 printLeg("<a name=\"mean_ev_$header\">$header /ev</a> - mean time and error for $header per $eventIs");
125 }
126 for $i (1 .. $#headers) {
127 print HTML "<th class=\"source\" colspan=2><a href=\"#mean_ev_$i\">ratio $i<br>/ev</a></th>\n";
128 printLeg("<a name=\"mean_ev_$i\">ratio $i /ev</a> - ratio and error of per $eventIs time, calculated as: (($headers[0] - $headers[$i])/$headers[$i])*100%, mean value");
129 }
130 }
131 print HTML "</tr>\n";
132 }
133 $legendDone = 1;
134 }
135
136 sub closeTable {
137 if($inTable) {
138 undef $inTable;
139 print HTML "</tr>\n";
140 print HTML "</tbody>";
141 print HTML "</table>\n";
142 }
143 }
144
145 sub newRow {
146 if(!$inTable) {
147 startTable;
148 } else {
149 print HTML "</tr>\n";
150 }
151 print HTML "<tr>";
152 }
153
154 sub outputData {
155 if($inTable) {
156 my $msg = shift;
157 my $align = shift;
158 print HTML "<td";
159 if($align) {
160 print HTML " align = $align>";
161 } else {
162 print HTML ">";
163 }
164 print HTML "$msg";
165 print HTML "</td>";
166 } else {
167 my $message;
168 foreach $message (@_) {
169 print HTML "$message";
170 }
171 }
172 }
173
174 sub setupOutput {
175 my $date = localtime;
176 my $options = shift;
177 %options = %{ $options };
178 my $title = $options{ "title" };
179 my $headers = $options{ "headers" };
180 if($options{ "operationIs" }) {
181 $operationIs = $options{ "operationIs" };
182 }
183 if($options{ "eventIs" }) {
184 $eventIs = $options{ "eventIs" };
185 }
186 @headers = split(/ /, $headers);
187 my ($t, $rest);
188 ($t, $rest) = split(/\.\w+/, $0);
189 $t =~ /^.*\W(\w+)$/;
190 $t = $1;
191 if($outType eq 'HTML') {
192 $html = $date;
193 $html =~ s/://g; # ':' illegal
194 $html =~ s/\s*\d+$//; # delete year
195 $html =~ s/^\w+\s*//; # delete dow
196 $html = "$t $html.html";
197 if($options{ "outputDir" }) {
198 $html = $options{ "outputDir" }."/".$html;
199 }
200 $html =~ s/ /_/g;
201
202 open(HTML,">$html") or die "Can't write to $html: $!";
203
204 #<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
205 print HTML <<EOF;
206 <HTML>
207 <HEAD>
208 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
209 <TITLE>$title</TITLE>
210 <style>
211 <!--
212 body { font-size: 10pt; font-family: sans-serif }
213 th { font-size: 10pt; border: 0 solid #000080; padding: 5 }
214 th.testNameHeader { border-width: 1 }
215 th.testName { text-align: left; border-left-width: 1; border-right-width: 1;
216 border-bottom-width: 1 }
217 th.source { border-right-width: 1; border-bottom-width: 1 }
218 th.sourceType { border-right-width: 1; border-top-width: 1; border-bottom-width: 1 }
219 td { font-size: 10pt; text-align: Right; border: 0 solid #000080; padding: 5 }
220 td.string { text-align: Left; border-bottom-width:1; border-right-width:1 }
221 td.sepvalue { border-bottom-width: 1; border-right-width: 1 }
222 td.value { border-bottom-width: 1 }
223 td.worse { color: #FF0000; font-weight: bold; border-bottom-width: 1 }
224 td.error { font-size: 75%; border-right-width: 1; border-bottom-width: 1 }
225 td.errorLarge { font-size: 75%; color: #FF0000; font-weight: bold; border-right-width: 1;
226 border-bottom-width: 1 }
227 A:link { color: black; font-weight: normal; text-decoration: none} /* unvisited links */
228 A:visited { color: blue; font-weight: normal; text-decoration: none } /* visited links */
229 A:hover { color: red; font-weight: normal; text-decoration: none } /* user hovers */
230 A:active { color: lime; font-weight: normal; text-decoration: none } /* active links */
231 -->
232 </style>
233 </HEAD>
234 <BODY bgcolor="#FFFFFF" LINK="#006666" VLINK="#000000">
235 EOF
236 print HTML "<H1>$title</H1>\n";
237
238 #print HTML "<H2>$TESTCLASS</H2>\n";
239 }
240 }
241
242 sub closeOutput {
243 if($outType eq 'HTML') {
244 if($inTable) {
245 closeTable;
246 }
247 $legend .= "</ul>\n";
248 print HTML $legend;
249 outputRaw();
250 print HTML <<EOF;
251 </BODY>
252 </HTML>
253 EOF
254 close(HTML) or die "Can't close $html: $!";
255 }
256 }
257
258
259 sub outputRaw {
260 print HTML "<h2>Raw data</h2>";
261 my $key;
262 my $i;
263 my $j;
264 my $k;
265 print HTML "<table $TABLEATTR>\n";
266 for $key (sort keys %raw) {
267 my $printkey = $key;
268 $printkey =~ s/\<br\>/ /g;
269 if($printEvents) {
270 if($key ne "") {
271 print HTML "<tr><th class=\"testNameHeader\" colspan = 7>$printkey</td></tr>\n"; # locale and data file
272 }
273 print HTML "<tr><th class=\"testName\">test name</th><th class=\"testName\">interesting arguments</th><th class=\"testName\">iterations</th><th class=\"testName\">operations</th><th class=\"testName\">mean time (ns)</th><th class=\"testName\">error (ns)</th><th class=\"testName\">events</th></tr>\n";
274 } else {
275 if($key ne "") {
276 print HTML "<tr><th class=\"testName\" colspan = 6>$printkey</td></tr>\n"; # locale and data file
277 }
278 print HTML "<tr><th class=\"testName\">test name</th><th class=\"testName\">interesting arguments</th><th class=\"testName\">iterations</th><th class=\"testName\">operations</th><th class=\"testName\">mean time (ns)</th><th class=\"testName\">error (ns)</th></tr>\n";
279 }
280 $printkey =~ s/[\<\>\/ ]//g;
281
282 my %done;
283 for $i ( $raw{$key} ) {
284 print HTML "<tr>";
285 for $j ( @$i ) {
286 my ($test, $args);
287 ($test, $args) = split(/,/, shift(@$j));
288
289 print HTML "<th class=\"testName\">";
290 if(!$done{$test}) {
291 print HTML "<a name=\"".$printkey."_".$test."\">".$test."</a>";
292 $done{$test} = 1;
293 } else {
294 print HTML $test;
295 }
296 print HTML "</th>";
297
298 print HTML "<td class=\"string\">".$args."</td>";
299
300 print HTML "<td class=\"sepvalue\">".shift(@$j)."</td>";
301 print HTML "<td class=\"sepvalue\">".shift(@$j)."</td>";
302
303 my @data = @{ shift(@$j) };
304 my $ds = Dataset->new(@data);
305 print HTML "<td class=\"sepvalue\">".formatNumber(4, $mult, $ds->getMean)."</td><td class=\"sepvalue\">".formatNumber(4, $mult, $ds->getError)."</td>";
306 if($#{ $j } >= 0) {
307 print HTML "<td class=\"sepvalue\">".shift(@$j)."</td>";
308 }
309 print HTML "</tr>\n";
310 }
311 }
312 }
313 }
314
315 sub store {
316 $raw{$current}[$exp++] = [@_];
317 }
318
319 sub outputRow {
320 #$raw{$current}[$exp++] = [@_];
321 my $testName = shift;
322 my @iterPerPass = @{shift(@_)};
323 my @noopers = @{shift(@_)};
324 my @timedata = @{shift(@_)};
325 my @noevents;
326 if($#_ >= 0) {
327 @noevents = @{shift(@_)};
328 }
329 if(!$inTable) {
330 if(@noevents) {
331 $printEvents = 1;
332 startTable;
333 } else {
334 startTable;
335 }
336 }
337 debug("No events: @noevents, $#noevents\n");
338
339 my $j;
340 my $loc = $current;
341 $loc =~ s/\<br\>/ /g;
342 $loc =~ s/[\<\>\/ ]//g;
343
344 # Finished one row of results. Outputting
345 newRow;
346 #outputData($testName, "LEFT");
347 print HTML "<th class=\"testName\"><a href=\"#".$loc."_".$testName."\">$testName</a></th>\n";
348 #outputData($iterCount);
349 #outputData($noopers[0], "RIGHT");
350 outputValue($noopers[0]);
351
352 if(!$printEvents) {
353 for $j ( 0 .. $#timedata ) {
354 my $perOperation = $timedata[$j]->divideByScalar($iterPerPass[$j]*$noopers[$j]); # time per operation
355 #debug("Time per operation: ".formatSeconds(4, $perOperation->getMean, $perOperation->getError)."\n");
356 outputDist($perOperation);
357 }
358 }
359 my $baseLinePO = $timedata[0]->divideByScalar($iterPerPass[0]*$noopers[0]);
360 for $j ( 1 .. $#timedata ) {
361 my $perOperation = $timedata[$j]->divideByScalar($iterPerPass[$j]*$noopers[$j]); # time per operation
362 my $ratio = $baseLinePO->subtract($perOperation);
363 $ratio = $ratio->divide($perOperation);
364 outputDist($ratio, "%");
365 }
366 if (@noevents) {
367 for $j ( 0 .. $#timedata ) {
368 #outputData($noevents[$j], "RIGHT");
369 outputValue($noevents[$j]);
370 }
371 for $j ( 0 .. $#timedata ) {
372 my $perEvent = $timedata[$j]->divideByScalar($iterPerPass[$j]*$noevents[$j]); # time per event
373 #debug("Time per operation: ".formatSeconds(4, $perEvent->getMean, $perEvent->getError)."\n");
374 outputDist($perEvent);
375 }
376 my $baseLinePO = $timedata[0]->divideByScalar($iterPerPass[0]*$noevents[0]);
377 for $j ( 1 .. $#timedata ) {
378 my $perOperation = $timedata[$j]->divideByScalar($iterPerPass[$j]*$noevents[$j]); # time per operation
379 my $ratio = $baseLinePO->subtract($perOperation);
380 $ratio = $ratio->divide($perOperation);
381 outputDist($ratio, "%");
382 }
383 }
384 }
385
386
387 1;
388
389 #eof