[jboss-user] [JBoss Microcontainer Development] New message: "Re: Optimizing ScopeKey"
Kabir Khan
do-not-reply at jboss.com
Fri Feb 12 09:57:57 EST 2010
User development,
A new message was posted in the thread "Optimizing ScopeKey":
http://community.jboss.org/message/526058#526058
Author : Kabir Khan
Profile : http://community.jboss.org/people/kabir.khan@jboss.com
Message:
--------------------------------------------------------------
Yes, the hashing function is broken
int iterations = 15;
public void testScopeKeyHashing()
{
List<ScopeKey> scopes = createScopeKeys();
List<ScopeKey> lockedScopes = createFroxenScopeKeys(scopes);
assertSame(scopes.size(), lockedScopes.size());
for (int i = 0 ; i < iterations ; i++)
{
assertTrue(scopes.get(i).equals(lockedScopes.get(i)));
assertTrue(lockedScopes.get(i).equals(scopes.get(i)));
assertEquals(scopes.get(i).hashCode(), lockedScopes.get(i).hashCode());
System.out.println(scopes.get(i).hashCode() + " " + scopes.get(i));
assertNotSame(scopes.get(i), lockedScopes.get(i));
}
}
private List<ScopeKey> createScopeKeys()
{
List<ScopeKey> keys = new ArrayList<ScopeKey>();
for (int i = 0 ; i < iterations ; i++)
{
ScopeKey scopeKey = ScopeKey.DEFAULT_SCOPE.clone();
scopeKey.addScope(CommonLevels.INSTANCE, "Bean" + i + Math.random() + 10000);
scopeKey.addScope(CommonLevels.CLASS, Object.class.getName());
keys.add(scopeKey);
}
return keys;
}
private List<ScopeKey> createFroxenScopeKeys(List<ScopeKey> scopes)
{
List<ScopeKey> frozens = new ArrayList<ScopeKey>();
for (ScopeKey key : scopes)
{
ScopeKey frozen = key.getOptimizedKey();
frozen.freeze();
frozens.add(frozen);
}
return frozens;
}
gives the same value 3400
> 3400 [JVM=THIS, APPLICATION=xyz0, CLASS=java.lang.Object, INSTANCE=Bean00.724748247059574310000]
>
> 3400 [JVM=THIS, APPLICATION=xyz1, CLASS=java.lang.Object, INSTANCE=Bean10.821575642383577510000]
>
> 3400 [JVM=THIS, APPLICATION=xyz2, CLASS=java.lang.Object, INSTANCE=Bean20.3658072070977499410000]
>
> 3400 [JVM=THIS, APPLICATION=xyz3, CLASS=java.lang.Object, INSTANCE=Bean30.17405710442802047
>
>
> 10000]
>
> 3400 [JVM=THIS, APPLICATION=xyz4, CLASS=java.lang.Object, INSTANCE=Bean40.328947822381441710000]
>
> 3400 [JVM=THIS, APPLICATION=xyz5, CLASS=java.lang.Object, INSTANCE=Bean50.853785127372253610000]
>
> 3400 [JVM=THIS, APPLICATION=xyz6, CLASS=java.lang.Object, INSTANCE=Bean60.308661441767311610000]
>
> 3400 [JVM=THIS, APPLICATION=xyz7, CLASS=java.lang.Object, INSTANCE=Bean70.3214439497564738310000]
>
> 3400 [JVM=THIS, APPLICATION=xyz8, CLASS=java.lang.Object, INSTANCE=Bean80.73783778624132910000]
>
> 3400 [JVM=THIS, APPLICATION=xyz9, CLASS=java.lang.Object, INSTANCE=Bean90.301807484250228210000]
>
> 3400 [JVM=THIS, APPLICATION=xyz10, CLASS=java.lang.Object, INSTANCE=Bean100.4474778106602691510000]
>
> 3400 [JVM=THIS, APPLICATION=xyz11, CLASS=java.lang.Object, INSTANCE=Bean110.1197707023336379610000]
>
> 3400 [JVM=THIS, APPLICATION=xyz12, CLASS=java.lang.Object, INSTANCE=Bean120.313969251914117510000]
>
> 3400 [JVM=THIS, APPLICATION=xyz13, CLASS=java.lang.Object, INSTANCE=Bean130.609491494722042910000]
>
> 3400 [JVM=THIS, APPLICATION=xyz14, CLASS=java.lang.Object, INSTANCE=Bean140.713736711778368310000]
>
>
That must be the real problem, causing UnmodifiableScopeKey.equals()->ScopeKey.getArray()->Collection.toArray() to be called too many times. Looking at the ScopeKey.computeHashCode function it only takes the levels into account:
protected static int computeHashCode(Iterable<Scope> scopeCollection)
{
int hashCode = 0;
for (Scope scope : scopeCollection)
hashCode += scope.getScopeLevel().hashCode();
return hashCode;
}
I've rewritten this to hash properly, which makes the retrievals map behave like a map, giving less ScopeKey.equals() hits
Scope constructor:
public Scope(ScopeLevel level, Object qualifier)
{
if (level == null)
throw new IllegalArgumentException("Null level");
if (qualifier == null)
throw new IllegalArgumentException("Null qualifier");
this.level = level;
this.qualifier = qualifier;
int hash = 17;
hash = 31 * hash + level.hashCode();
hash = 31 * hash + qualifier.hashCode();
hashcode = hash;
}
protected static int computeHashCode(Iterable<Scope> scopeCollection)
{
int hashCode = 0;
for (Scope scope : scopeCollection)
//hashCode += scope.getScopeLevel().hashCode();
hashCode += scope.hashCode();
return hashCode;
}
I'll add a test and commit against https://jira.jboss.org/jira/browse/JBMDR-65 and then see what this does to AS boot times
--------------------------------------------------------------
To reply to this message visit the message page: http://community.jboss.org/message/526058#526058
More information about the jboss-user
mailing list