diff --git a/infer/src/cost/costModels.ml b/infer/src/cost/costModels.ml index 0fab779b0..cf4921f24 100644 --- a/infer/src/cost/costModels.ml +++ b/infer/src/cost/costModels.ml @@ -48,6 +48,12 @@ module BoundsOf (Container : CostUtils.S) = struct let log_n = logarithmic_length exp ~of_function cost_model_env mem ~ret in let n = linear_length exp ~of_function cost_model_env mem ~ret in BasicCost.mult n log_n + + + let op_on_two_lengths exp1 exp2 ~f cost_model_env ~ret mem ~of_function = + let n = linear_length exp1 ~of_function cost_model_env mem ~ret in + let m = linear_length exp2 ~of_function cost_model_env mem ~ret in + f n m end module IntHashMap = struct @@ -282,6 +288,10 @@ module Call = struct ; +PatternMatch.Java.implements_collection &:: "contains" <>$ capt_exp $+...$--> BoundsOfCollection.linear_length ~of_function:"Collection.contains" + ; +PatternMatch.Java.implements_collection + &:: "containsAll" <>$ capt_exp $+ capt_exp + $+...$--> BoundsOfCollection.op_on_two_lengths ~f:BasicCost.mult + ~of_function:"Collection.containsAll" ; +PatternMatch.Java.implements_collections &:: "binarySearch" <>$ capt_exp $+...$--> BoundsOfCollection.logarithmic_length ~of_function:"Collections.binarySearch" diff --git a/infer/tests/codetoanalyze/java/performance/CollectionTest.java b/infer/tests/codetoanalyze/java/performance/CollectionTest.java index 9f8bfc061..005e01ddc 100644 --- a/infer/tests/codetoanalyze/java/performance/CollectionTest.java +++ b/infer/tests/codetoanalyze/java/performance/CollectionTest.java @@ -104,6 +104,11 @@ public class CollectionTest { for (int i = 0; i < set.size(); i++) {} } + // O(|keyMap| x |coll|) + void containsAll_quadratic(HashMap keyMap, Collection coll) { + keyMap.values().containsAll(coll); + } + void containsNull_linear(HashMap keyMap) { keyMap.values().contains(null); } diff --git a/infer/tests/codetoanalyze/java/performance/cost-issues.exp b/infer/tests/codetoanalyze/java/performance/cost-issues.exp index 94bf50b90..961cc48c6 100644 --- a/infer/tests/codetoanalyze/java/performance/cost-issues.exp +++ b/infer/tests/codetoanalyze/java/performance/cost-issues.exp @@ -99,6 +99,7 @@ codetoanalyze/java/performance/CollectionTest.java, CollectionTest$MyEnumType.(), 2, OnUIThread:false, [] +codetoanalyze/java/performance/CollectionTest.java, CollectionTest.containsAll_quadratic(java.util.HashMap,java.util.Collection):void, 6 + coll.length × keyMap.length, OnUIThread:false, [{keyMap.length},Modeled call to Collection.containsAll,{coll.length},Modeled call to Collection.containsAll] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.containsNull_linear(java.util.HashMap):void, 5 + keyMap.length, OnUIThread:false, [{keyMap.length},Modeled call to Collection.contains] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.ensure_call(CollectionTest$MyCollection):void, 9 + 5 ⋅ list.length, OnUIThread:false, [{list.length},Call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.immutable_set_of_constant():void, 9, OnUIThread:false, []