Improve pooling stats

This commit is contained in:
Clément Fournier
2020-04-20 08:07:04 +02:00
parent 1c4b241255
commit 7f65b1f910

View File

@ -5,9 +5,9 @@
package net.sourceforge.pmd.lang.ast.impl.javacc;
import java.util.HashMap;
import java.util.LongSummaryStatistics;
import java.util.Map;
import java.util.WeakHashMap;
import net.sourceforge.pmd.util.document.Chars;
@ -19,12 +19,12 @@ import net.sourceforge.pmd.util.document.Chars;
*/
public final class StringPool {
// This will be constant-folded by the JIT, use false in production
private static final boolean COLLECT_STATS = false;
private static final Stats stats = new Stats();
private static final Stats STATS = new Stats();
private static final String[] SINGLE_CHARS;
static {
// all ascii characters
SINGLE_CHARS = new String[128];
@ -34,12 +34,15 @@ public final class StringPool {
}
private final Map<Chars, String> pool = new HashMap<>();
private final Map<Chars, String> pool = new WeakHashMap<>();
String toString(CharSequence c, boolean doPool) {
if (c.length() == 1) {
char fst = c.charAt(0);
if (fst < 128) {
if (COLLECT_STATS) {
STATS.addCacheHit(1);
}
return SINGLE_CHARS[fst];
}
}
@ -49,10 +52,10 @@ public final class StringPool {
return pool.compute((Chars) c,
(chars, s) -> {
if (s != null) {
stats.addCacheHit(s.length());
STATS.addCacheHit(s.length());
return s;
} else {
stats.addCacheMiss(chars.length());
STATS.addCacheMiss(chars.length());
return chars.toString();
}
});
@ -61,13 +64,15 @@ public final class StringPool {
}
}
if (COLLECT_STATS) {
stats.addPass(c);
STATS.addPass(c);
}
return c.toString();
}
public static void printStats() {
stats.print();
if (COLLECT_STATS) {
STATS.print();
}
}
private static class Stats {
@ -84,15 +89,15 @@ public final class StringPool {
System.err.println("String pool stats");
System.err.println("=================");
System.err.println("Hits: " + hits + " (" + (hits * 100 / (total() + 1)) + "% of " + total() + ")");
System.err.println("Hit length (net savings): " + hitLen + " " + toSize(hitLen));
System.err.println(
"Total pool size: " + poolContents.getCount() + " strings (" + toSize(poolContents.getSum()) + ")");
System.err.println("Hit length (net savings): " + hitLen + " (" + toSize(hitLen) + ")");
System.err.println("Total pool size: " + poolContents.getCount() + " strings (" + toSize(poolContents.getSum()) + ")");
System.err.println("Avg pooled string length: " + poolContents.getAverage() + " chars");
System.err.println("Unpooled string length: " + notPooledAlloc + " chars (" + toSize(notPooledAlloc) + ")");
}
private String toSize(long charLen) {
// assuming all pooled chars are latin-1, so 1B in a compressed string (byte[], not char[])
// Assuming all pooled chars are latin-1, so 1B in a compressed string (byte[], not char[])
// Before Java 9, it's twice as much
if (charLen > (1 << 20)) {
return (charLen >> 20) + " MB";
} else if (charLen > (1 << 10)) {