Improve pooling stats
This commit is contained in:
@ -5,9 +5,9 @@
|
|||||||
package net.sourceforge.pmd.lang.ast.impl.javacc;
|
package net.sourceforge.pmd.lang.ast.impl.javacc;
|
||||||
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LongSummaryStatistics;
|
import java.util.LongSummaryStatistics;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import net.sourceforge.pmd.util.document.Chars;
|
import net.sourceforge.pmd.util.document.Chars;
|
||||||
|
|
||||||
@ -19,12 +19,12 @@ import net.sourceforge.pmd.util.document.Chars;
|
|||||||
*/
|
*/
|
||||||
public final class StringPool {
|
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 boolean COLLECT_STATS = false;
|
||||||
private static final Stats stats = new Stats();
|
private static final Stats STATS = new Stats();
|
||||||
|
|
||||||
private static final String[] SINGLE_CHARS;
|
private static final String[] SINGLE_CHARS;
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// all ascii characters
|
// all ascii characters
|
||||||
SINGLE_CHARS = new String[128];
|
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) {
|
String toString(CharSequence c, boolean doPool) {
|
||||||
if (c.length() == 1) {
|
if (c.length() == 1) {
|
||||||
char fst = c.charAt(0);
|
char fst = c.charAt(0);
|
||||||
if (fst < 128) {
|
if (fst < 128) {
|
||||||
|
if (COLLECT_STATS) {
|
||||||
|
STATS.addCacheHit(1);
|
||||||
|
}
|
||||||
return SINGLE_CHARS[fst];
|
return SINGLE_CHARS[fst];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,10 +52,10 @@ public final class StringPool {
|
|||||||
return pool.compute((Chars) c,
|
return pool.compute((Chars) c,
|
||||||
(chars, s) -> {
|
(chars, s) -> {
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
stats.addCacheHit(s.length());
|
STATS.addCacheHit(s.length());
|
||||||
return s;
|
return s;
|
||||||
} else {
|
} else {
|
||||||
stats.addCacheMiss(chars.length());
|
STATS.addCacheMiss(chars.length());
|
||||||
return chars.toString();
|
return chars.toString();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -61,13 +64,15 @@ public final class StringPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (COLLECT_STATS) {
|
if (COLLECT_STATS) {
|
||||||
stats.addPass(c);
|
STATS.addPass(c);
|
||||||
}
|
}
|
||||||
return c.toString();
|
return c.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printStats() {
|
public static void printStats() {
|
||||||
stats.print();
|
if (COLLECT_STATS) {
|
||||||
|
STATS.print();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Stats {
|
private static class Stats {
|
||||||
@ -84,15 +89,15 @@ public final class StringPool {
|
|||||||
System.err.println("String pool stats");
|
System.err.println("String pool stats");
|
||||||
System.err.println("=================");
|
System.err.println("=================");
|
||||||
System.err.println("Hits: " + hits + " (" + (hits * 100 / (total() + 1)) + "% of " + total() + ")");
|
System.err.println("Hits: " + hits + " (" + (hits * 100 / (total() + 1)) + "% of " + total() + ")");
|
||||||
System.err.println("Hit length (net savings): " + hitLen + " " + toSize(hitLen));
|
System.err.println("Hit length (net savings): " + hitLen + " (" + toSize(hitLen) + ")");
|
||||||
System.err.println(
|
System.err.println("Total pool size: " + poolContents.getCount() + " strings (" + toSize(poolContents.getSum()) + ")");
|
||||||
"Total pool size: " + poolContents.getCount() + " strings (" + toSize(poolContents.getSum()) + ")");
|
|
||||||
System.err.println("Avg pooled string length: " + poolContents.getAverage() + " chars");
|
System.err.println("Avg pooled string length: " + poolContents.getAverage() + " chars");
|
||||||
System.err.println("Unpooled string length: " + notPooledAlloc + " chars (" + toSize(notPooledAlloc) + ")");
|
System.err.println("Unpooled string length: " + notPooledAlloc + " chars (" + toSize(notPooledAlloc) + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toSize(long charLen) {
|
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)) {
|
if (charLen > (1 << 20)) {
|
||||||
return (charLen >> 20) + " MB";
|
return (charLen >> 20) + " MB";
|
||||||
} else if (charLen > (1 << 10)) {
|
} else if (charLen > (1 << 10)) {
|
||||||
|
Reference in New Issue
Block a user