Performance Optimisations on Project Setup

"Sorry I kinda put them into a single commit" - shedaniel

- Fix AtRemapper into not using ZipUtil#transformEntries, which is slow as it transverses the whole zip tree
- Optimises InnerClassRemapper into not using ZipUtil#iterate, which provides the InputStream of the ZipEntry, data that we don't utilize. Switch to a simple FileSystem to traverse through the list of files
- Make MappingsProvider respect mergedv2 yarn files, skipping merging and reordering namespaces in the process. Users that wish to benefit from this should switch to using mergedv2 yarn artifacts
- Make MinecraftMappedProvider only read inputs once
- Replace (TinyRemapper, official -> named) to (AsmRemapper, intermediary -> named), and chain it to the (TinyRemapper, official -> intermediary) to avoid reading the Minecraft jar again
- Multi-thread MinecraftPatchedProvider#fixParameterAnnotation properly

On a typical project, these changes can save up to 50% of the import time. Tested on architectury example mod, which brought import times from 1m 51s to 48s.
This commit is contained in:
shedaniel
2021-04-22 23:41:35 +08:00
parent b200c4ff62
commit 001f4b58f6
10 changed files with 311 additions and 43 deletions

View File

@@ -29,6 +29,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -121,4 +122,33 @@ public class ThreadingUtils {
public interface UnsafeConsumer<T> {
void accept(T value) throws Throwable;
}
public static TaskCompleter taskCompleter() {
return new TaskCompleter();
}
public static class TaskCompleter {
List<CompletableFuture<?>> tasks = new ArrayList<>();
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public TaskCompleter add(UnsafeRunnable job) {
tasks.add(CompletableFuture.runAsync(() -> {
try {
job.run();
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}, service));
return this;
}
public void complete() {
try {
CompletableFuture.allOf(tasks.toArray(new CompletableFuture[0])).get();
service.shutdownNow();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
}