performance optimization

This commit is contained in:
Florian Steurer 2016-04-20 11:25:45 +02:00
parent 904ca01207
commit 6a42c8ef11
5 changed files with 75 additions and 48 deletions

View File

@ -50,12 +50,6 @@ public class MartelliMontanariUnify implements IUnify {
TypeParams rhsTypeParams = rhsType.getTypeParams(); TypeParams rhsTypeParams = rhsType.getTypeParams();
TypeParams lhsTypeParams = lhsType.getTypeParams(); TypeParams lhsTypeParams = lhsType.getTypeParams();
// DELETE - Rule
if(pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx);
continue;
}
// REDUCE - Rule // REDUCE - Rule
if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) { if(!(rhsType instanceof PlaceholderType) && !(lhsType instanceof PlaceholderType)) {
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
@ -78,6 +72,12 @@ public class MartelliMontanariUnify implements IUnify {
termsList.addAll(result); termsList.addAll(result);
continue; continue;
} }
// DELETE - Rule
if(pair.getRhsType().equals(pair.getLhsType())) {
termsList.remove(idx);
continue;
}
// SWAP - Rule // SWAP - Rule
if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) { if(!(lhsType instanceof PlaceholderType) && (rhsType instanceof PlaceholderType)) {

View File

@ -106,10 +106,10 @@ public class FiniteClosure implements IFiniteClosure {
// Permute all params with values that are in smArg() of that type. // Permute all params with values that are in smArg() of that type.
// This corresponds to Case 3 in the definition of the subtyping relation. // This corresponds to Case 3 in the definition of the subtyping relation.
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); /*{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (UnifyType param : type.getTypeParams()) for (UnifyType param : type.getTypeParams())
paramCandidates.add(smArg(param)); 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. // This is case 2 of the definition of the subtyping relation.
Set<UnifyType> result2 = new HashSet<>(); Set<UnifyType> result2 = new HashSet<>();
@ -117,23 +117,24 @@ public class FiniteClosure implements IFiniteClosure {
HashSet<UnifyType> candidates = new HashSet<>(); HashSet<UnifyType> candidates = new HashSet<>();
// All types with the same name // All types with the same name
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
for(UnifyType typePrime : result1) { //for(UnifyType typePrime : result1) {
for (UnifyType theta2 : candidates) { for (UnifyType theta2 : candidates) {
// Find the substitution // Find the substitution
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2); Optional<Unifier> sigma2Opt = unify.unify(type, theta2);
if (!sigma2Opt.isPresent()) if (!sigma2Opt.isPresent())
continue; continue;
Unifier sigma2 = sigma2Opt.get(); Unifier sigma2 = sigma2Opt.get();
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams()); if(sigma2.size() == 0)
if(type.equals(theta2)) continue;
continue; sigma2.swapPlaceholderSubstitutions(type.getTypeParams());
Set<UnifyType> theta1s = smaller(theta2); //if(type.equals(theta2))
for (UnifyType theta1 : theta1s) { // continue;
// Because only the most general type is calculated, sigma1 = sigma2 Set<UnifyType> theta1s = smaller(theta2);
UnifyType sigma1Theta1 = sigma2.apply(theta1); for (UnifyType theta1 : theta1s) {
result2.add(sigma1Theta1); // Because only the most general type is calculated, sigma1 = sigma2
} UnifyType sigma1Theta1 = sigma2.apply(theta1);
} result2.add(sigma1Theta1);
}
} }
} }
else else
@ -210,10 +211,10 @@ public class FiniteClosure implements IFiniteClosure {
// Permute all params with values that are in smArg() of that type. // Permute all params with values that are in smArg() of that type.
// This corresponds to Case 3 in the definition of the subtyping relation. // This corresponds to Case 3 in the definition of the subtyping relation.
{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>(); /*{ArrayList<Set<UnifyType>> paramCandidates = new ArrayList<>();
for (UnifyType param : type.getTypeParams()) for (UnifyType param : type.getTypeParams())
paramCandidates.add(grArg(param)); 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. // This is case 2 of the definition of the subtyping relation.
Set<UnifyType> result2 = new HashSet<>(); Set<UnifyType> result2 = new HashSet<>();
@ -221,24 +222,27 @@ public class FiniteClosure implements IFiniteClosure {
HashSet<UnifyType> candidates = new HashSet<>(); HashSet<UnifyType> candidates = new HashSet<>();
// All types with the same name // All types with the same name
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent())); strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
for(UnifyType typePrime : result1) { // for(UnifyType typePrime : result1)
for (UnifyType theta2 : candidates) { for (UnifyType theta2 : candidates) {
// Find the substitution // Find the substitution
Optional<Unifier> sigma2Opt = unify.unify(typePrime, theta2); Optional<Unifier> sigma2Opt = unify.unify(type, theta2);
if (!sigma2Opt.isPresent()) if (!sigma2Opt.isPresent())
continue; continue;
if(type.equals(theta2)) //if (type.equals(theta2))
continue; // continue;
Unifier sigma2 = sigma2Opt.get(); Unifier sigma2 = sigma2Opt.get();
sigma2.swapPlaceholderSubstitutions(typePrime.getTypeParams()); if(sigma2.size() == 0) // type.equals(theta2)
Set<UnifyType> theta1s = greater(theta2); continue;
for (UnifyType theta1 : theta1s) { sigma2.swapPlaceholderSubstitutions(type.getTypeParams());
// Because only the most general type is calculated, sigma1 = sigma2 Set<UnifyType> theta1s = greater(theta2);
UnifyType sigma1Theta1 = sigma2.apply(theta1); for (UnifyType theta1 : theta1s) {
result2.add(sigma1Theta1); // Because only the most general type is calculated, sigma1
} // = sigma2
UnifyType sigma1Theta1 = sigma2.apply(theta1);
result2.add(sigma1Theta1);
} }
// }
} }
} }

View File

@ -15,6 +15,11 @@ public final class TypeParams implements Iterable<UnifyType>{
*/ */
private final UnifyType[] typeParams; private final UnifyType[] typeParams;
/**
* Hashcode calculation is expensive and must be cached.
*/
private final int hashCode;
/** /**
* Creates a new set of type parameters. * Creates a new set of type parameters.
* @param types The type parameters. * @param types The type parameters.
@ -23,6 +28,9 @@ public final class TypeParams implements Iterable<UnifyType>{
typeParams = new UnifyType[types.size()]; typeParams = new UnifyType[types.size()];
for(int i=0;i<types.size();i++) for(int i=0;i<types.size();i++)
typeParams[i] = types.get(i); typeParams[i] = types.get(i);
// Hashcode calculation is expensive and must be cached.
hashCode = Arrays.hashCode(typeParams);
} }
/** /**
@ -31,6 +39,9 @@ public final class TypeParams implements Iterable<UnifyType>{
*/ */
public TypeParams(UnifyType... types) { public TypeParams(UnifyType... types) {
typeParams = 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<UnifyType>{
@Override @Override
public int hashCode() { public int hashCode() {
return Arrays.hashCode(typeParams); return hashCode;
} }
@Override @Override

View File

@ -81,6 +81,13 @@ public class Unifier implements Function<UnifyType, UnifyType>, Iterable<Entry<P
return substitutions.get(t); return substitutions.get(t);
} }
/**
* The number of substitutions in the unifier. If zero, this is the identity function.
*/
public int size() {
return substitutions.size();
}
/** /**
* Garantuees that if there is a substitutions (a -> b) in this unifier, * Garantuees that if there is a substitutions (a -> b) in this unifier,
* a is not an element of the targetParams. Substitutions that do not * a is not an element of the targetParams. Substitutions that do not

View File

@ -9,18 +9,20 @@ public class UnifyPair {
/** /**
* The type on the left hand side of the pair. * 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. * 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. * The operator that determines the relation between the left and right hand side type.
*/ */
private PairOperator pairOp; private PairOperator pairOp;
private final int hashCode;
/** /**
* Creates a new instance of the pair. * Creates a new instance of the pair.
* @param lhs The type on the left hand side 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.lhs = lhs;
this.rhs = rhs; this.rhs = rhs;
pairOp = op; pairOp = op;
// Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
} }
/** /**
@ -68,7 +73,7 @@ public class UnifyPair {
@Override @Override
public int hashCode() { public int hashCode() {
return 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode(); return hashCode;
} }
@Override @Override