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