Release coccinelle-0.2.4
[bpt/coccinelle.git] / tools / process_isoprofile.ml
1 (*
2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
7 *
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
11 *
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
22 *)
23
24
25 (*
26 * Copyright 2010, INRIA, University of Copenhagen
27 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
28 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
29 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
30 * This file is part of Coccinelle.
31 *
32 * Coccinelle is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, according to version 2 of the License.
35 *
36 * Coccinelle is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
43 *
44 * The authors reserve the right to distribute this or future versions of
45 * Coccinelle under other licenses.
46 *)
47
48
49 (* This is for processing information created with the -profile_iso option.
50 Runs are assumed separated with a line beginning with =.
51 The first run is discarded *)
52
53 let is_marker l = String.get l 0 = '='
54 let is_nothing l = String.sub l 0 2 = "ls"
55
56 let skip_start i = (* skip over the ========== at the beginning *)
57 let rec loop _ =
58 let l = input_line i in
59 if not (is_marker l)
60 then loop() in
61 loop()
62
63 let get_data l =
64 match Str.split (Str.regexp ":") l with
65 [_;after] ->
66 (match Str.split (Str.regexp " sec") after with
67 [info;_] -> float_of_string info
68 | _ -> failwith "bad data")
69 | _ -> failwith (Printf.sprintf "bad data %s" l)
70
71 type more = MORE | NOMORE | INFO of float * float * float * float | CONT
72
73 let read_data_one i =
74 try
75 let start = input_line i in (* three lines of header *)
76 if is_marker start
77 then MORE
78 else if is_nothing start
79 then CONT
80 else
81 let _ = input_line i in
82 let _ = input_line i in
83 (match
84 List.sort compare
85 [input_line i;input_line i;input_line i;input_line i]
86 with
87 [asttoctl;full_engine;mysat;parse_cocci] ->
88 if String.get full_engine 0 = '*'
89 then (let _ = input_line i in CONT) (* hack!!! *)
90 else
91 let asttoctl = get_data asttoctl in
92 let full_engine = get_data full_engine in
93 let mysat = get_data mysat in
94 let parse_cocci = get_data parse_cocci in
95 INFO(full_engine,mysat,parse_cocci,asttoctl)
96 | _ -> failwith "not possible")
97 with End_of_file -> NOMORE
98
99 let read_data i =
100 skip_start i;
101 let optcons x y = if x = [] then y else x::y in
102 let rec loop all_acc acc =
103 match read_data_one i with
104 NOMORE -> optcons acc all_acc
105 | MORE -> loop (optcons acc all_acc) []
106 | CONT -> loop all_acc acc
107 | INFO(a,b,c,d) -> loop all_acc ((a,b,c,d)::acc) in
108 let table = loop [] [] in
109 let all_infos = (* a list with a list of information for each file *)
110 List.fold_left
111 (function all_infos ->
112 function one_run ->
113 List.map2 (function ainfo -> function orun -> orun::ainfo)
114 all_infos one_run)
115 (List.map (function _ -> []) (List.hd table))
116 table in
117 let overheads =
118 List.concat
119 (List.map (List.map (function (_,x,y,z) -> x+.y+.z)) all_infos) in
120 let total_times =
121 List.concat
122 (List.map (List.map (function (x,_,_,_) -> x)) all_infos) in
123 let mysat_times =
124 List.concat
125 (List.map (List.map (function (_,x,_,_) -> x)) all_infos) in
126 let parse_time =
127 List.concat
128 (List.map (List.map (function (_,_,x,y) -> x +. y)) all_infos) in
129 (overheads,total_times,mysat_times,parse_time)
130
131 let percent pct = (int_of_float ((100.0 *. pct) +. 0.5)) - 100
132 let mpercent pct = (int_of_float ((100.0 *. pct) +. 0.5))
133 let minf l = List.fold_left min (List.hd l) l
134 let maxf l = List.fold_left max (List.hd l) l
135
136 let ave = function
137 [] -> 0.0
138 | l ->
139 let total = List.fold_left (+.) 0.0 l in
140 total /. (float_of_int(List.length l))
141
142 let process_files iso_file noiso_file =
143 let i = open_in iso_file in
144 let (iso_over,iso_total,iso_mysat,iso_parse) = read_data i in
145 close_in i;
146 let i = open_in noiso_file in
147 let (noiso_over,noiso_total,noiso_mysat,noiso_parse) = read_data i in
148 close_in i;
149 Printf.printf "isos: min %f max %f ave %f\n"
150 (minf iso_total) (maxf iso_total) (ave iso_total);
151 Printf.printf "noisos: min %f max %f ave %f\n"
152 (minf noiso_total) (maxf noiso_total) (ave noiso_total);
153 Printf.printf "Overhead in total time %d%%: min %f max %f\n"
154 (percent (ave (List.map2 (/.) iso_total noiso_total)))
155 (minf (List.map2 (-.) iso_total noiso_total))
156 (maxf (List.map2 (-.) iso_total noiso_total));
157 Printf.printf "Portion of overhead due to parsing %d%%: min %f max %f\n"
158 (mpercent
159 (ave (List.fold_left2
160 (function acc ->
161 (function (iso_total,iso_parse) ->
162 (function (noiso_total,noiso_parse) ->
163 let total_ovd = iso_total -. noiso_total in
164 let parse_ovd = iso_parse -. noiso_parse in
165 if total_ovd < 0.001 or parse_ovd > total_ovd or
166 parse_ovd < 0.0
167 then acc
168 else (parse_ovd /. total_ovd) :: acc)))
169 []
170 (List.combine iso_total iso_parse)
171 (List.combine noiso_total noiso_parse))))
172 (minf (List.map2 (-.) iso_parse noiso_parse))
173 (maxf (List.map2 (-.) iso_parse noiso_parse));
174 Printf.printf "Portion of overhead due to matching %d%%: min %f max %f\n\n"
175 (mpercent
176 (ave (List.fold_left2
177 (function acc ->
178 (function (iso_total,iso_mysat) ->
179 (function (noiso_total,noiso_mysat) ->
180 let total_ovd = iso_total -. noiso_total in
181 let mysat_ovd = iso_mysat -. noiso_mysat in
182 if total_ovd < 0.001 or mysat_ovd > total_ovd or
183 mysat_ovd < 0.0
184 then acc
185 else (mysat_ovd /. total_ovd) :: acc)))
186 []
187 (List.combine iso_total iso_mysat)
188 (List.combine noiso_total noiso_mysat))))
189 (minf (List.map2 (-.) iso_mysat noiso_mysat))
190 (maxf (List.map2 (-.) iso_mysat noiso_mysat))
191
192 let _ =
193 let iso = Array.get Sys.argv 1 in
194 let noiso = Array.get Sys.argv 2 in
195 process_files iso noiso