Attempt to reduce overhead of splitting same path string many times

This commit is contained in:
embeddedt 2025-05-18 21:05:05 -04:00
parent a643170426
commit 3a2edf7ddd
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
2 changed files with 22 additions and 4 deletions

View File

@ -16,6 +16,7 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -24,6 +25,8 @@ import java.util.stream.Stream;
*/ */
public class PackResourcesCacheEngine { public class PackResourcesCacheEngine {
private static final Joiner SLASH_JOINER = Joiner.on('/'); private static final Joiner SLASH_JOINER = Joiner.on('/');
private static final ConcurrentHashMap<String, String> PATH_COMPONENT_INTERNER = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, String[]> CACHED_SPLIT_PATHS = new ConcurrentHashMap<>();
static class Node { static class Node {
Map<String, Node> children; Map<String, Node> children;
@ -100,7 +103,6 @@ public class PackResourcesCacheEngine {
// used for log message // used for log message
this.debugPath = basePathRetriever.apply(PackType.CLIENT_RESOURCES).toAbsolutePath(); this.debugPath = basePathRetriever.apply(PackType.CLIENT_RESOURCES).toAbsolutePath();
this.root.children = new Object2ObjectOpenHashMap<>(); this.root.children = new Object2ObjectOpenHashMap<>();
ObjectOpenHashSet<String> pathKeys = new ObjectOpenHashSet<>();
for(PackType type : PackType.values()) { for(PackType type : PackType.values()) {
var typeRoot = new Node(); var typeRoot = new Node();
this.root.children.put(type.getDirectory(), typeRoot); this.root.children.put(type.getDirectory(), typeRoot);
@ -114,8 +116,12 @@ public class PackResourcesCacheEngine {
.filter(PackResourcesCacheEngine::isValidCachedResourcePath) .filter(PackResourcesCacheEngine::isValidCachedResourcePath)
.forEach(path -> { .forEach(path -> {
var node = typeRoot; var node = typeRoot;
for (Path component : path) { int nameCount = path.getNameCount();
String key = pathKeys.addOrGet(component.toString()); for (int i = 0; i < nameCount; i++) {
String key = path.getName(i).toString();
if (i < (nameCount - 1)) {
key = PATH_COMPONENT_INTERNER.computeIfAbsent(key, Function.identity());
}
if (node.children == null) { if (node.children == null) {
node.children = new Object2ObjectOpenHashMap<>(); node.children = new Object2ObjectOpenHashMap<>();
} }
@ -205,4 +211,16 @@ public class PackResourcesCacheEngine {
} }
node.collectResources(resourceNamespace, this.rootPathsByType.get(type).resolve(resourceNamespace), components, 0, maxDepth, output); node.collectResources(resourceNamespace, this.rootPathsByType.get(type).resolve(resourceNamespace), components, 0, maxDepth, output);
} }
private static String[] decompose(String path) {
String[] components = path.split("/");
for (int i = 0; i < components.length; i++) {
components[i] = PATH_COMPONENT_INTERNER.computeIfAbsent(components[i], Function.identity());
}
return components;
}
public static String[] decomposeCached(String path) {
return CACHED_SPLIT_PATHS.computeIfAbsent(path, PackResourcesCacheEngine::decompose);
}
} }

View File

@ -102,6 +102,6 @@ public abstract class ForgePathPackResourcesMixin implements ICachingResourcePac
if(!PackTypeHelper.isVanillaPackType(type)) if(!PackTypeHelper.isVanillaPackType(type))
return; return;
ci.cancel(); ci.cancel();
this.generateResourceCache().collectResources(type, namespace, path.split("/"), Integer.MAX_VALUE, resourceOutput); this.generateResourceCache().collectResources(type, namespace, PackResourcesCacheEngine.decomposeCached(path), Integer.MAX_VALUE, resourceOutput);
} }
} }