From c1d7eaacb57f8bc85e25e0b5813d8d7cbb055daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20=C3=96NCEL?= Date: Wed, 17 Feb 2021 19:00:04 +0300 Subject: [PATCH] Fix NumberFormatException stack performance. Creating exceptions is not cheap, since they construct stack frames. This shouldn't affect performance much, but fix/optimize it anyway. --- .../BytecodeVersionAnalyzer.java | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/lifemcserver/bytecodeversionanalyzer/BytecodeVersionAnalyzer.java b/src/main/java/com/lifemcserver/bytecodeversionanalyzer/BytecodeVersionAnalyzer.java index a306e78..62c2df6 100644 --- a/src/main/java/com/lifemcserver/bytecodeversionanalyzer/BytecodeVersionAnalyzer.java +++ b/src/main/java/com/lifemcserver/bytecodeversionanalyzer/BytecodeVersionAnalyzer.java @@ -670,6 +670,32 @@ private static final Map getClassFileVersionsInJar(fin return jarEntryVersionConsumer.classes; } + /** + * Checks if the given {@link CharSequence} is a digit. + * Uses {@link Character#isDigit(char)}, but checks for all characters. + *

+ * It also supports negative digits. + * + * @param cs The {@link CharSequence} to check. + * @return True if the {@link CharSequence} only consists of digits. + */ + private static final boolean isDigit(final CharSequence cs) { + final int csLength = cs.length(); + + for (int i = 0; i < csLength; i++) { + //noinspection MagicCharacter + if (i == 0 && cs.charAt(i) == '-') { + continue; + } + + if (!Character.isDigit(cs.charAt(i))) { + return false; + } + } + + return true; + } + /** * Determines if the given {@link JarEntry} should be skipped. *

@@ -685,16 +711,8 @@ private static final boolean shouldSkip(final JarEntry entry, final JarEntry old if (entry.getName().contains("$") && entry.hashCode() == oldEntry.hashCode()) { // Compiler generated class (not necessarily a fully generated class, maybe just a nested class) and is not versioned final String[] nestedClassSplit = dollarPattern.split(entry.getName()); - boolean compilerGeneratedNonSourceClass = true; - try { - // If it is a fully generated class, compiler formats it like ClassName$.class, where is a number, i.e. 1 - Integer.parseInt(dotClassPatternMatcher.reset(nestedClassSplit[1]).replaceAll(Matcher.quoteReplacement(""))); - } catch (final NumberFormatException e) { - // It is a sub-class - compilerGeneratedNonSourceClass = false; - } - - if (compilerGeneratedNonSourceClass) { // A synthetic accessor class, or an anonymous/lambda class. + // If it is a fully generated class, compiler formats it like ClassName$.class, where is a number, i.e. 1 + if (isDigit(dotClassPatternMatcher.reset(nestedClassSplit[1]).replaceAll(""))) { // A synthetic accessor class, or an anonymous/lambda class. final String baseClassName = nestedClassSplit[0] + ".class"; final JarEntry baseClassJarEntry = jar.getJarEntry(baseClassName);