Some profiling results

This commit is contained in:
Johannes Frohnmeyer 2022-01-24 15:04:03 +01:00
parent b14a8fbed1
commit 86e0f00253
Signed by: Johannes
GPG Key ID: E76429612C2929F4
10 changed files with 64 additions and 14 deletions

3
.gitignore vendored
View File

@ -4,4 +4,5 @@ build/
run*/
imgui.ini
hs_err_pid*
inceptum.log
inceptum.log
bin

View File

@ -47,7 +47,7 @@ public class InceptumGui {
try {
for (Path path : Utils.ls(MetaHolder.INSTANCE_DIR)) {
if (Files.exists(path.resolve("instance.json")))
ModsDirScanner.get(path, Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class)).start();
ModsDirScanner.get(path.resolve("mods"), Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class)).start();
}
} catch (IOException e) {
Utils.LOGGER.error("Could not initialize MDS");

View File

@ -13,6 +13,7 @@ import io.gitlab.jfronny.inceptum.model.mojang.VersionsList;
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Tuple;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.util.api.McApi;
@ -33,6 +34,7 @@ public class InstanceManageControls {
private final ImInt fabricVersion = new ImInt(0);
private final ImBoolean snapshots = new ImBoolean(ConfigHolder.CONFIG.snapshots);
private final ImBoolean fabric = new ImBoolean(true);
private final Map<Tuple<String, String>, VersionInfo> versionInfoCache = new HashMap<>();
private VersionsListInfo selected;
private FabricVersionLoaderInfo selectedFabric;
@ -126,9 +128,13 @@ public class InstanceManageControls {
}
public VersionInfo getVersionInfo() throws IOException {
VersionInfo vi = McApi.getVersionInfo(selected);
if (fabric.get()) FabricMetaApi.addFabric(vi, selectedFabric.loader.version, FabricMetaApi.FabricVersionInfoType.Both);
return vi;
Tuple<String, String> key = new Tuple<>(selected.id, fabric.get() ? selectedFabric.loader.version : "");
if (!versionInfoCache.containsKey(key)) {
VersionInfo vi = McApi.getVersionInfo(selected);
if (fabric.get()) FabricMetaApi.addFabric(vi, selectedFabric.loader.version, FabricMetaApi.FabricVersionInfoType.Both);
versionInfoCache.put(key, vi);
}
return versionInfoCache.get(key);
}
public LoaderInfo getLoaderInfo() {

View File

@ -32,7 +32,7 @@ public class InstanceView {
}
InstanceMeta instance;
try {
instance = Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class);
instance = Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class); //TODO investigate the perf impact of this
} catch (IOException e) {
Utils.LOGGER.error("Could not load instance.json", e);
continue;

View File

@ -86,7 +86,7 @@ public class ModDescription {
public void addSource(ModSource source, String gameVersion) {
try {
sources.put(source, source.getUpdate(gameVersion));
sources.put(source, source.getUpdate(gameVersion)); //TODO only fetch updates on first check
} catch (IOException e) {
Utils.LOGGER.error("Could not check " + source.getName() + " for updates", e);
}

View File

@ -0,0 +1,4 @@
package io.gitlab.jfronny.inceptum.util;
public record Tuple<T1, T2>(T1 left, T2 right) {
}

View File

@ -72,7 +72,7 @@ public record FileScanTask(Path file, BiConsumer<Path, IWModDescription> discove
}
ModSource selectedSource = null;
for (ModSource source : md.sources.keySet()) {
source.getUpdate(gameVersion);
source.getUpdate(gameVersion); //TODO only check once for ID
if (!Files.exists(source.getJarPath())) source.download();
selectedSource = source;
}

View File

@ -14,7 +14,7 @@ import java.util.function.BiConsumer;
public class ModsDirScanner implements Closeable {
private static final Map<Path, ModsDirScanner> SCANNERS = new HashMap<>();
private static final ExecutorService POOL = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
private static final ExecutorService POOL = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new NamedThreadFactory("mds"));
private final Map<Path, IWModDescription> descriptions = new HashMap<>();
private final Set<Path> scannedPaths = new HashSet<>();
private final Thread th;
@ -25,7 +25,7 @@ public class ModsDirScanner implements Closeable {
private ModsDirScanner(Path modsDir, InstanceMeta instance) {
this.modsDir = modsDir;
this.instance = instance;
this.th = new Thread(this::scanTaskInternal);
this.th = new Thread(this::scanTaskInternal, "mds-" + modsDir.getParent().getFileName());
}
public static ModsDirScanner get(Path modsDir, InstanceMeta instance) {
@ -92,20 +92,29 @@ public class ModsDirScanner implements Closeable {
private void scanTaskInternal() {
while (!disposed) {
runOnce(descriptions::put);
runOnce((path, iwModDescription) -> {});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void runOnce(BiConsumer<Path, IWModDescription> discovered) {
try {
if (!Files.isDirectory(modsDir)) {
Thread.sleep(5000);
return;
}
Set<Future<?>> tasks = new HashSet<>();
String mc = instance.getMinecraftVersion();
discovered = discovered.andThen((path, iwModDescription) -> {
scannedPaths.add(path);
descriptions.put(path, iwModDescription);
});
for (Path mods : Utils.ls(modsDir)) {
if (disposed) return;
tasks.add(POOL.submit(new FileScanTask(mods, discovered.andThen((path, iwModDescription) -> scannedPaths.add(path)), getGameVersion())));
tasks.add(POOL.submit(new FileScanTask(mods, discovered, mc)));
}
for (Future<?> task : tasks) {
try {
@ -114,7 +123,6 @@ public class ModsDirScanner implements Closeable {
Utils.LOGGER.error("Failed to execute ScanTask", e);
}
}
Thread.sleep(100);
} catch (IOException | InterruptedException e) {
Utils.LOGGER.error("Could not list mods", e);
}

View File

@ -0,0 +1,30 @@
package io.gitlab.jfronny.inceptum.util.mds;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class NamedThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public NamedThreadFactory(String name) {
SecurityManager s = System.getSecurityManager();
this.group = s != null ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
this.namePrefix = name + "-pool-" + poolNumber.getAndIncrement() + "-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(this.group, r, this.namePrefix + this.threadNumber.getAndIncrement(), 0L);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != 5) {
t.setPriority(5);
}
return t;
}
}

View File

@ -56,6 +56,7 @@ public class Utils {
return downloadObject(url, () -> downloadString(url, sha1), s -> GsonHolder.getGson().fromJson(s, type));
}
//TODO memory-based cache to avoid gson
private static <T> T downloadObject(String url, ThrowingSupplier<String, Exception> sourceString, Function<String, T> builder) throws IOException {
Path cache = MetaHolder.CACHE_DIR.resolve(HashUtils.sha1(url.getBytes(StandardCharsets.UTF_8)));
if (Files.exists(cache))