minor performance optimizations:

- Evaluate shortname once for classloading request
- Smaller read action scope
- No read action for Loader.containsName, the containment data is constant after Loader initialization
This commit is contained in:
Maxim.Mossienko
2018-10-22 16:57:58 +02:00
parent 483be03dfe
commit 95b6f375df
2 changed files with 27 additions and 31 deletions
@@ -108,20 +108,20 @@ public class ClassPath {
public Resource getResource(String s) {
final long started = startTiming();
try {
String shortName = ClasspathCache.transformName(s);
int i;
if (myCanUseCache) {
boolean allUrlsWereProcessed = myAllUrlsWereProcessed;
i = allUrlsWereProcessed ? 0 : myLastLoaderProcessed.get();
Resource prevResource = myCache.iterateLoaders(s, ourResourceIterator, s, this);
Resource prevResource = myCache.iterateLoaders(s, ourResourceIterator, s, this, shortName);
if (prevResource != null || allUrlsWereProcessed) return prevResource;
}
else {
i = 0;
}
String shortName = ClasspathCache.transformName(s);
Loader loader;
while ((loader = getLoader(i++)) != null) {
if (myCanUseCache) {
@@ -292,12 +292,12 @@ public class ClassPath {
if (myCanUseCache && myAllUrlsWereProcessed) {
Collection<Loader> loadersSet = new LinkedHashSet<Loader>();
myCache.iterateLoaders(name, ourLoaderCollector, loadersSet, this);
myCache.iterateLoaders(name, ourLoaderCollector, loadersSet, this, myShortName);
if (name.endsWith("/")) {
myCache.iterateLoaders(name.substring(0, name.length() - 1), ourLoaderCollector, loadersSet, this);
myCache.iterateLoaders(name.substring(0, name.length() - 1), ourLoaderCollector, loadersSet, this, myShortName);
} else {
myCache.iterateLoaders(name + "/", ourLoaderCollector, loadersSet, this);
myCache.iterateLoaders(name + "/", ourLoaderCollector, loadersSet, this, myShortName);
}
loaders = new ArrayList<Loader>(loadersSet);
@@ -358,8 +358,8 @@ public class ClassPath {
private static class ResourceStringLoaderIterator extends ClasspathCache.LoaderIterator<Resource, String, ClassPath> {
@Override
Resource process(Loader loader, String s, ClassPath classPath) {
if (!classPath.myCache.loaderHasName(s, ClasspathCache.transformName(s), loader)) return null;
Resource process(Loader loader, String s, ClassPath classPath, String shortName) {
if (!classPath.myCache.loaderHasName(s, shortName, loader)) return null;
Resource resource = loader.getResource(s);
if (resource != null) printOrder(loader, s, resource);
return resource;
@@ -368,7 +368,7 @@ public class ClassPath {
private static class LoaderCollector extends ClasspathCache.LoaderIterator<Object, Collection<Loader>, Object> {
@Override
Object process(Loader loader, Collection<Loader> parameter, Object parameter2) {
Object process(Loader loader, Collection<Loader> parameter, Object parameter2, String shortName) {
parameter.add(loader);
return null;
}
@@ -455,7 +455,7 @@ public class ClassPath {
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook for tracing classloading information") {
@Override
public void run() {
System.out.println("Classloading requests:" + ourTotalRequests + ", time:" + (ourTotalTime.get() / 1000000) + "ms");
System.out.println("Classloading requests:" + ClassPath.class.getClassLoader() + "," + ourTotalRequests + ", time:" + (ourTotalTime.get() / 1000000) + "ms");
}
});
}
@@ -138,33 +138,36 @@ public class ClasspathCache {
abstract static class LoaderIterator <ResultType, ParameterType, ParameterType2> {
@Nullable
abstract ResultType process(Loader loader, ParameterType parameter, ParameterType2 parameter2);
abstract ResultType process(Loader loader, ParameterType parameter, ParameterType2 parameter2, String shortName);
}
@Nullable <ResultType, ParameterType, ParameterType2> ResultType iterateLoaders(
String resourcePath,
LoaderIterator<ResultType, ParameterType, ParameterType2> iterator,
ParameterType parameter,
ParameterType2 parameter2) {
ParameterType2 parameter2,
String shortName) {
Object o;
myLock.readLock().lock();
try {
IntObjectHashMap map = resourcePath.endsWith(UrlClassLoader.CLASS_EXTENSION) ?
myClassPackagesCache : myResourcePackagesCache;
Object o = map.get(getPackageNameHash(resourcePath));
if (o == null) return null;
if (o instanceof Loader) return iterator.process((Loader)o, parameter, parameter2);
Loader[] loaders = (Loader[])o;
for(Loader l:loaders) {
ResultType result = iterator.process(l, parameter, parameter2);
if (result != null) return result;
}
return null;
o = map.get(getPackageNameHash(resourcePath));
}
finally {
myLock.readLock().unlock();
}
if (o == null) return null;
if (o instanceof Loader) return iterator.process((Loader)o, parameter, parameter2, shortName);
Loader[] loaders = (Loader[])o;
for(Loader l:loaders) {
ResultType result = iterator.process(l, parameter, parameter2, shortName);
if (result != null) return result;
}
return null;
}
static int getPackageNameHash(String resourcePath) {
@@ -185,17 +188,10 @@ public class ClasspathCache {
}
}
public boolean loaderHasName(String name, String shortName, Loader loader) {
boolean loaderHasName(String name, String shortName, Loader loader) {
if (StringUtil.isEmpty(name)) return true;
myLock.readLock().lock();
try {
return loader.containsName(name, shortName);
}
finally {
myLock.readLock().unlock();
}
return loader.containsName(name, shortName);
}
static String transformName(String name) {