[followup] Log PNG/SVG icons load time statistics

Now logs both PNG & SVG stats in one run.
This commit is contained in:
Anton Tarasov
2018-01-23 19:19:48 +03:00
parent c4a91e5d41
commit ac272ef608
2 changed files with 37 additions and 20 deletions
@@ -9,9 +9,9 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.FieldAccessor;
import com.intellij.util.ImageLoader;
import com.intellij.util.ImageLoader.ImageDesc.Type;
import com.intellij.util.ImageLoader.LoadFunction;
import org.jetbrains.annotations.NotNull;
@@ -35,10 +35,15 @@ public class IconsLoadTime extends DumbAwareAction {
private static final int STATS_LIMIT = 10000;
private static final int FIXED_SCOPE = 100; // log stats for a first fixed number of icons
private static final List<Integer> stats = IS_INTERNAL_MODE ? Collections.synchronizedList(new LinkedList<>()) : null; // load time per icon
// load time per icon
private static final List<Integer> statsSVG = IS_INTERNAL_MODE ? Collections.synchronizedList(new LinkedList<>()) : null;
private static final List<Integer> statsPNG = IS_INTERNAL_MODE ? Collections.synchronizedList(new LinkedList<>()) : null;
static {
if (IS_INTERNAL_MODE) new FieldAccessor<>(ImageLoader.class, "measureLoad").set(null, (LoadFunction)func -> measure(Objects.requireNonNull(func)));
if (IS_INTERNAL_MODE) {
new FieldAccessor<>(ImageLoader.class, "measureLoad").set(null,
(LoadFunction)(func, type) -> measure(Objects.requireNonNull(func), Objects.requireNonNull(type)));
}
}
@Override
@@ -46,7 +51,13 @@ public class IconsLoadTime extends DumbAwareAction {
log(false);
}
private static void log(boolean measureStartupLoad) {
public static void log(boolean measureStartupLoad) {
log(measureStartupLoad, Type.PNG);
log(measureStartupLoad, Type.SVG);
}
private static void log(boolean measureStartupLoad, Type type) {
List<Integer> stats = getStats(type);
if (stats == null || stats.isEmpty()) return;
int size = stats.size();
@@ -56,31 +67,37 @@ public class IconsLoadTime extends DumbAwareAction {
Function<Long, String> ms = (nano) -> String.format("%.02fms", nano / 1000000f);
LOG.info((Registry.is("ide.svg.icon") ? "SVG" : "PNG") +
" load time: " +
LOG.info(type + " load time: " +
(measureStartupLoad ? "ide_startup=" : "total=") + ms.apply(sum) +
", average=" + ms.apply(average) +
", median=" + ms.apply(median) +
"; number of icons: " + size);
}
private static Image measure(LoadFunction func) throws IOException {
private static Image measure(LoadFunction func, Type type) throws IOException {
List<Integer> stats = getStats(type);
boolean measure = stats.size() < STATS_LIMIT;
long t = measure ? System.nanoTime() : 0;
Image img = func.load(null);
Image img = func.load(null, null);
if (measure) {
stats.add((int)(System.nanoTime() - t));
if (stats.size() == FIXED_SCOPE) log(false);
if (stats.size() == FIXED_SCOPE) log(false, type);
}
return img;
}
private static List<Integer> getStats(Type type) {
return type == Type.SVG ? statsSVG : statsPNG;
}
public static class StartupLoadTime implements StartupActivity, DumbAware {
@Override
public void runActivity(@NotNull Project project) {
if (IS_INTERNAL_MODE) log(true);
if (IS_INTERNAL_MODE) {
log(true);
}
}
}
}
@@ -61,10 +61,10 @@ public class ImageLoader implements Serializable {
* For internal usage.
*/
public interface LoadFunction {
Image load(@Nullable LoadFunction delegate) throws IOException;
Image load(@Nullable LoadFunction delegate, @Nullable ImageDesc.Type type) throws IOException;
}
private static class ImageDesc {
public static class ImageDesc {
public enum Type {
PNG,
@@ -73,14 +73,14 @@ public class ImageLoader implements Serializable {
public Image load(final URL url, final InputStream is, final double scale) throws IOException {
LoadFunction f = new LoadFunction() {
@Override
public Image load(LoadFunction delegate) throws IOException {
public Image load(LoadFunction delegate, Type type) throws IOException {
return SVGLoader.load(url, is, scale);
}
};
if (measureLoad != null && Registry.is("ide.svg.icon")) {
return measureLoad.load(f);
if (measureLoad != null) {
return measureLoad.load(f, SVG);
}
return f.load(null);
return f.load(null, null);
}
},
@@ -89,14 +89,14 @@ public class ImageLoader implements Serializable {
public Image load(final URL url, final InputStream is, final double scale) throws IOException {
LoadFunction f = new LoadFunction() {
@Override
public Image load(LoadFunction delegate) {
public Image load(LoadFunction delegate, Type type) {
return ImageLoader.load(is, scale);
}
};
if (measureLoad != null && !Registry.is("ide.svg.icon")) {
return measureLoad.load(f);
if (measureLoad != null) {
return measureLoad.load(f, PNG);
}
return f.load(null);
return f.load(null, null);
}
}