From 6a42c8ef119e3a86cd853baebf6ddf07e1bea1fc Mon Sep 17 00:00:00 2001 From: Florian Steurer Date: Wed, 20 Apr 2016 11:25:45 +0200 Subject: [PATCH] performance optimization --- .../unify/MartelliMontanariUnify.java | 12 +-- .../unify/model/FiniteClosure.java | 80 ++++++++++--------- .../typeinference/unify/model/TypeParams.java | 13 ++- .../typeinference/unify/model/Unifier.java | 7 ++ .../typeinference/unify/model/UnifyPair.java | 11 ++- 5 files changed, 75 insertions(+), 48 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java index 80dabce6..1c75ea99 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/MartelliMontanariUnify.java @@ -50,12 +50,6 @@ public class MartelliMontanariUnify implements IUnify { TypeParams rhsTypeParams = rhsType.getTypeParams(); TypeParams lhsTypeParams = lhsType.getTypeParams(); - // DELETE - Rule - if(pair.getRhsType().equals(pair.getLhsType())) { - termsList.remove(idx); - continue; - } - // REDUCE - Rule if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) { Set result = new HashSet<>(); @@ -78,6 +72,12 @@ public class MartelliMontanariUnify implements IUnify { termsList.addAll(result); continue; } + + // DELETE - Rule + if(pair.getRhsType().equals(pair.getLhsType())) { + termsList.remove(idx); + continue; + } // SWAP - Rule if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) { diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 17fbb240..ac0862cc 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -106,10 +106,10 @@ public class FiniteClosure implements IFiniteClosure { // Permute all params with values that are in smArg() of that type. // This corresponds to Case 3 in the definition of the subtyping relation. - {ArrayList> paramCandidates = new ArrayList<>(); + /*{ArrayList> paramCandidates = new ArrayList<>(); for (UnifyType param : type.getTypeParams()) paramCandidates.add(smArg(param)); - permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));} + permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}*/ // This is case 2 of the definition of the subtyping relation. Set result2 = new HashSet<>(); @@ -117,23 +117,24 @@ public class FiniteClosure implements IFiniteClosure { HashSet candidates = new HashSet<>(); // All types with the same name strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); - for(UnifyType typePrime : result1) { - for (UnifyType theta2 : candidates) { - // Find the substitution - Optional sigma2Opt = unify.unify(typePrime, theta2); - if (!sigma2Opt.isPresent()) - continue; - Unifier sigma2 = sigma2Opt.get(); - sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams()); - if(type.equals(theta2)) - continue; - Set theta1s = smaller(theta2); - for (UnifyType theta1 : theta1s) { - // Because only the most general type is calculated, sigma1 = sigma2 - UnifyType sigma1Theta1 = sigma2.apply(theta1); - result2.add(sigma1Theta1); - } - } + //for(UnifyType typePrime : result1) { + for (UnifyType theta2 : candidates) { + // Find the substitution + Optional sigma2Opt = unify.unify(type, theta2); + if (!sigma2Opt.isPresent()) + continue; + Unifier sigma2 = sigma2Opt.get(); + if(sigma2.size() == 0) + continue; + sigma2.swapPlaceholderSubstitutions(type.getTypeParams()); + //if(type.equals(theta2)) + // continue; + Set theta1s = smaller(theta2); + for (UnifyType theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 = sigma2 + UnifyType sigma1Theta1 = sigma2.apply(theta1); + result2.add(sigma1Theta1); + } } } else @@ -210,10 +211,10 @@ public class FiniteClosure implements IFiniteClosure { // Permute all params with values that are in smArg() of that type. // This corresponds to Case 3 in the definition of the subtyping relation. - {ArrayList> paramCandidates = new ArrayList<>(); + /*{ArrayList> paramCandidates = new ArrayList<>(); for (UnifyType param : type.getTypeParams()) paramCandidates.add(grArg(param)); - permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));} + permuteParams(paramCandidates).forEach(x -> result1.add(type.setTypeParams(x)));}*/ // This is case 2 of the definition of the subtyping relation. Set result2 = new HashSet<>(); @@ -221,24 +222,27 @@ public class FiniteClosure implements IFiniteClosure { HashSet candidates = new HashSet<>(); // All types with the same name strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); - - for(UnifyType typePrime : result1) { - for (UnifyType theta2 : candidates) { - // Find the substitution - Optional sigma2Opt = unify.unify(typePrime, theta2); - if (!sigma2Opt.isPresent()) - continue; - if(type.equals(theta2)) - continue; - Unifier sigma2 = sigma2Opt.get(); - sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams()); - Set theta1s = greater(theta2); - for (UnifyType theta1 : theta1s) { - // Because only the most general type is calculated, sigma1 = sigma2 - UnifyType sigma1Theta1 = sigma2.apply(theta1); - result2.add(sigma1Theta1); - } + + // for(UnifyType typePrime : result1) + for (UnifyType theta2 : candidates) { + // Find the substitution + Optional sigma2Opt = unify.unify(type, theta2); + if (!sigma2Opt.isPresent()) + continue; + //if (type.equals(theta2)) + // continue; + Unifier sigma2 = sigma2Opt.get(); + if(sigma2.size() == 0) // type.equals(theta2) + continue; + sigma2.swapPlaceholderSubstitutions(type.getTypeParams()); + Set theta1s = greater(theta2); + for (UnifyType theta1 : theta1s) { + // Because only the most general type is calculated, sigma1 + // = sigma2 + UnifyType sigma1Theta1 = sigma2.apply(theta1); + result2.add(sigma1Theta1); } + // } } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index aa534b60..7ce251d9 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -15,6 +15,11 @@ public final class TypeParams implements Iterable{ */ private final UnifyType[] typeParams; + /** + * Hashcode calculation is expensive and must be cached. + */ + private final int hashCode; + /** * Creates a new set of type parameters. * @param types The type parameters. @@ -23,6 +28,9 @@ public final class TypeParams implements Iterable{ typeParams = new UnifyType[types.size()]; for(int i=0;i{ */ public TypeParams(UnifyType... types) { typeParams = types; + + // Hashcode calculation is expensive and must be cached. + hashCode = Arrays.hashCode(typeParams); } /** @@ -108,7 +119,7 @@ public final class TypeParams implements Iterable{ @Override public int hashCode() { - return Arrays.hashCode(typeParams); + return hashCode; } @Override diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java index 1a3988db..dbcc9b39 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/Unifier.java @@ -81,6 +81,13 @@ public class Unifier implements Function, Iterable b) in this unifier, * a is not an element of the targetParams. Substitutions that do not diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java index ed2c95ef..62de0c96 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java @@ -9,18 +9,20 @@ public class UnifyPair { /** * The type on the left hand side of the pair. */ - private UnifyType lhs; + private final UnifyType lhs; /** * The type on the right hand side of the pair. */ - private UnifyType rhs; + private final UnifyType rhs; /** * The operator that determines the relation between the left and right hand side type. */ private PairOperator pairOp; + private final int hashCode; + /** * Creates a new instance of the pair. * @param lhs The type on the left hand side of the pair. @@ -31,6 +33,9 @@ public class UnifyPair { this.lhs = lhs; this.rhs = rhs; pairOp = op; + + // Caching hashcode + hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); } /** @@ -68,7 +73,7 @@ public class UnifyPair { @Override public int hashCode() { - return 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); + return hashCode; } @Override