[Perf] Count polynomials costs when computing differential

Reviewed By: mbouaziz

Differential Revision: D9082078

fbshipit-source-id: 5932d04db
master
Martino Luca 6 years ago committed by Facebook Github Bot
parent df80ccda08
commit 974e134061

@ -53,7 +53,84 @@ let dedup (issues: Jsonbug_t.jsonbug list) =
|> snd |> sort_by_location |> snd |> sort_by_location
type t = {introduced: Jsonbug_t.report; fixed: Jsonbug_t.report; preexisting: Jsonbug_t.report} module CostsSummary : sig
val to_json :
current_report:Jsonbug_t.report -> previous_report:Jsonbug_t.report -> Yojson.Basic.json
end = struct
type 'a count = {top: 'a; zero: 'a; degrees: 'a Int.Map.t}
let init = {top= 0; zero= 0; degrees= Int.Map.empty}
type previous_current = {previous: int; current: int}
let zero_token_str =
Format.asprintf "%a" Itv.NonNegativePolynomial.pp Itv.NonNegativePolynomial.zero
let top_token_str =
Format.asprintf "%a" Itv.NonNegativePolynomial.pp Itv.NonNegativePolynomial.top
let count report =
let count_aux t (e: Jsonbug_t.extra) =
match e with
| {cost_polynomial= Some cp} when String.equal cp zero_token_str ->
{t with zero= t.zero + 1}
| {cost_polynomial= Some cp; cost_degree= None} when String.equal cp top_token_str ->
{t with top= t.top + 1}
| {cost_degree= Some v} ->
let degrees = Int.Map.update t.degrees v ~f:(function None -> 1 | Some x -> x + 1) in
{t with degrees}
| {cost_degree= None} ->
t
in
List.fold ~init
~f:(fun acc v -> match v.Jsonbug_t.extras with None -> acc | Some v -> count_aux acc v)
report
let pair_counts ~current_counts ~previous_counts =
let compute_degrees current previous =
let merge_aux ~key:_ v =
match v with
| `Both (current, previous) ->
Some {current; previous}
| `Left current ->
Some {current; previous= 0}
| `Right previous ->
Some {current= 0; previous}
in
Int.Map.merge ~f:merge_aux current previous
in
{ top= {current= current_counts.top; previous= previous_counts.top}
; zero= {current= current_counts.zero; previous= previous_counts.zero}
; degrees= compute_degrees current_counts.degrees previous_counts.degrees }
let to_json ~current_report ~previous_report =
let current_counts = count current_report in
let previous_counts = count previous_report in
let paired_counts = pair_counts ~current_counts ~previous_counts in
let json_degrees =
Int.Map.to_alist ~key_order:`Increasing paired_counts.degrees
|> List.map ~f:(fun (key, {current; previous}) ->
`Assoc [("degree", `Int key); ("current", `Int current); ("previous", `Int previous)]
)
in
let create_assoc current previous =
`Assoc [("current", `Int current); ("previous", `Int previous)]
in
`Assoc
[ ("top", create_assoc paired_counts.top.current paired_counts.top.previous)
; ("zero", create_assoc paired_counts.zero.current paired_counts.zero.previous)
; ("degrees", `List json_degrees) ]
end
type t =
{ introduced: Jsonbug_t.report
; fixed: Jsonbug_t.report
; preexisting: Jsonbug_t.report
; costs_summary: Yojson.Basic.json }
(** Set operations should keep duplicated issues with identical hashes *) (** Set operations should keep duplicated issues with identical hashes *)
let of_reports ~(current_report: Jsonbug_t.report) ~(previous_report: Jsonbug_t.report) : t = let of_reports ~(current_report: Jsonbug_t.report) ~(previous_report: Jsonbug_t.report) : t =
@ -74,12 +151,15 @@ let of_reports ~(current_report: Jsonbug_t.report) ~(previous_report: Jsonbug_t.
let introduced, preexisting, fixed = let introduced, preexisting, fixed =
Map.fold2 (to_map current_report) (to_map previous_report) ~f:fold_aux ~init:([], [], []) Map.fold2 (to_map current_report) (to_map previous_report) ~f:fold_aux ~init:([], [], [])
in in
{introduced= dedup introduced; fixed= dedup fixed; preexisting= dedup preexisting} let costs_summary = CostsSummary.to_json ~current_report ~previous_report in
{introduced= dedup introduced; fixed= dedup fixed; preexisting= dedup preexisting; costs_summary}
let to_files {introduced; fixed; preexisting} destdir = let to_files {introduced; fixed; preexisting; costs_summary} destdir =
Out_channel.write_all (destdir ^/ "introduced.json") Out_channel.write_all (destdir ^/ "introduced.json")
~data:(Jsonbug_j.string_of_report introduced) ; ~data:(Jsonbug_j.string_of_report introduced) ;
Out_channel.write_all (destdir ^/ "fixed.json") ~data:(Jsonbug_j.string_of_report fixed) ; Out_channel.write_all (destdir ^/ "fixed.json") ~data:(Jsonbug_j.string_of_report fixed) ;
Out_channel.write_all (destdir ^/ "preexisting.json") Out_channel.write_all (destdir ^/ "preexisting.json")
~data:(Jsonbug_j.string_of_report preexisting) ~data:(Jsonbug_j.string_of_report preexisting) ;
Out_channel.write_all (destdir ^/ "costs_summary.json")
~data:(Yojson.Basic.to_string costs_summary)

@ -7,7 +7,11 @@
open! IStd open! IStd
type t = {introduced: Jsonbug_t.report; fixed: Jsonbug_t.report; preexisting: Jsonbug_t.report} type t =
{ introduced: Jsonbug_t.report
; fixed: Jsonbug_t.report
; preexisting: Jsonbug_t.report
; costs_summary: Yojson.Basic.json }
val of_reports : current_report:Jsonbug_t.report -> previous_report:Jsonbug_t.report -> t val of_reports : current_report:Jsonbug_t.report -> previous_report:Jsonbug_t.report -> t

@ -145,7 +145,7 @@ let skip_duplicated_types_on_filenames renamings (diff: Differential.t) : Differ
, list_map_fst preexisting' @ diff.preexisting , list_map_fst preexisting' @ diff.preexisting
, list_map_fst fixed_normalized' ) , list_map_fst fixed_normalized' )
in in
{introduced; fixed; preexisting} {introduced; fixed; preexisting; costs_summary= diff.costs_summary}
let java_anon_class_pattern = Str.regexp "\\$[0-9]+" let java_anon_class_pattern = Str.regexp "\\$[0-9]+"
@ -210,7 +210,10 @@ let skip_anonymous_class_renamings (diff: Differential.t) : Differential.t =
let introduced, preexisting, fixed = let introduced, preexisting, fixed =
relative_complements ~compare ~pred diff.introduced diff.fixed relative_complements ~compare ~pred diff.introduced diff.fixed
in in
{introduced; fixed; preexisting= preexisting @ diff.preexisting} { introduced
; fixed
; preexisting= preexisting @ diff.preexisting
; costs_summary= diff.costs_summary }
(* Strip issues whose paths are not among those we're interested in *) (* Strip issues whose paths are not among those we're interested in *)
@ -248,7 +251,8 @@ let do_filter (diff: Differential.t) (renamings: FileRenamings.t) ~(skip_duplica
in in
{ introduced= apply_paths_filter_if_needed `Introduced diff'.introduced { introduced= apply_paths_filter_if_needed `Introduced diff'.introduced
; fixed= apply_paths_filter_if_needed `Fixed diff'.fixed ; fixed= apply_paths_filter_if_needed `Fixed diff'.fixed
; preexisting= apply_paths_filter_if_needed `Preexisting diff'.preexisting } ; preexisting= apply_paths_filter_if_needed `Preexisting diff'.preexisting
; costs_summary= diff'.costs_summary }
module VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY = struct module VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY = struct

Loading…
Cancel
Save