mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-28 04:07:01 -05:00
Optimize DeobfSpecContext by scanning configurations individually (#1439)
* Optimize DeobfSpecContext by scanning configurations individually Previously, DeobfSpecContext used getFullClasspath().getFiles() which resolved the union of all configurations at once. This was extremely slow (~9.8s with FAPI). * Cleanup * Cleanup * Cleanup
This commit is contained in:
@@ -63,34 +63,57 @@ public record DeobfSpecContext(List<FabricModJson> modDependencies,
|
||||
|
||||
public static DeobfSpecContext create(DeobfProjectView projectView) {
|
||||
AsyncCache<List<FabricModJson>> fmjCache = new AsyncCache<>();
|
||||
List<FabricModJson> dependentMods = getDependentMods(projectView, fmjCache);
|
||||
Map<String, FabricModJson> mods = dependentMods.stream()
|
||||
.collect(HashMap::new, (map, mod) -> map.put(mod.getId(), mod), Map::putAll);
|
||||
|
||||
FileCollection mainRuntimeClasspath = projectView.getDependencies(DebofConfiguration.RUNTIME, DebofConfiguration.TargetSourceSet.MAIN);
|
||||
FileCollection mainCompileClasspath = projectView.getDependencies(DebofConfiguration.COMPILE, DebofConfiguration.TargetSourceSet.MAIN);
|
||||
|
||||
// All mods in both [runtimeClasspath, compileClasspath]
|
||||
Set<String> mainTransformingModIds = common(
|
||||
getModIds(mainRuntimeClasspath, fmjCache),
|
||||
getModIds(mainCompileClasspath, fmjCache)
|
||||
);
|
||||
List<FabricModJson> mainRuntimeMods = getModsFromConfiguration(mainRuntimeClasspath, fmjCache);
|
||||
List<FabricModJson> mainCompileMods = getModsFromConfiguration(mainCompileClasspath, fmjCache);
|
||||
|
||||
Set<String> mainRuntimeModIds = toModIdSet(mainRuntimeMods);
|
||||
Set<String> mainCompileModIds = toModIdSet(mainCompileMods);
|
||||
Set<String> mainTransformingModIds = common(mainRuntimeModIds, mainCompileModIds);
|
||||
|
||||
// All mods in both [runtimeClientClasspath, compileClientClasspath]
|
||||
List<FabricModJson> clientRuntimeMods;
|
||||
List<FabricModJson> clientCompileMods;
|
||||
Set<String> clientTransformingModIds;
|
||||
|
||||
if (projectView.areEnvironmentSourceSetsSplit()) {
|
||||
FileCollection clientRuntimeClasspath = projectView.getDependencies(DebofConfiguration.RUNTIME, DebofConfiguration.TargetSourceSet.CLIENT);
|
||||
FileCollection clientCompileClasspath = projectView.getDependencies(DebofConfiguration.COMPILE, DebofConfiguration.TargetSourceSet.CLIENT);
|
||||
|
||||
clientTransformingModIds = common(
|
||||
getModIds(clientRuntimeClasspath, fmjCache),
|
||||
getModIds(clientCompileClasspath, fmjCache)
|
||||
);
|
||||
clientRuntimeMods = getModsFromConfiguration(clientRuntimeClasspath, fmjCache);
|
||||
clientCompileMods = getModsFromConfiguration(clientCompileClasspath, fmjCache);
|
||||
|
||||
Set<String> clientRuntimeModIds = toModIdSet(clientRuntimeMods);
|
||||
Set<String> clientCompileModIds = toModIdSet(clientCompileMods);
|
||||
clientTransformingModIds = common(clientRuntimeModIds, clientCompileModIds);
|
||||
} else {
|
||||
clientRuntimeMods = List.of();
|
||||
clientCompileMods = List.of();
|
||||
clientTransformingModIds = Set.of();
|
||||
}
|
||||
|
||||
// Build the full list of dependent mods from all configurations
|
||||
List<FabricModJson> allMods = new ArrayList<>();
|
||||
allMods.addAll(mainRuntimeMods);
|
||||
allMods.addAll(mainCompileMods);
|
||||
allMods.addAll(clientRuntimeMods);
|
||||
allMods.addAll(clientCompileMods);
|
||||
|
||||
// Add project dependencies
|
||||
if (!projectView.disableProjectDependantMods()) {
|
||||
for (Project dependentProject : SpecContext.getDependentProjects(projectView).toList()) {
|
||||
allMods.addAll(fmjCache.getBlocking(dependentProject.getPath(), () -> FabricModJsonHelpers.getModsInProject(dependentProject)));
|
||||
}
|
||||
}
|
||||
|
||||
List<FabricModJson> dependentMods = SpecContext.distinctSorted(allMods);
|
||||
Map<String, FabricModJson> mods = dependentMods.stream()
|
||||
.collect(HashMap::new, (map, mod) -> map.put(mod.getId(), mod), Map::putAll);
|
||||
|
||||
// All dependency mods that are on both the compile and runtime classpath
|
||||
List<FabricModJson> modDependenciesCompileRuntime = new ArrayList<>(getMods(mods, combine(mainTransformingModIds, clientTransformingModIds)));
|
||||
|
||||
@@ -108,9 +131,8 @@ public record DeobfSpecContext(List<FabricModJson> modDependencies,
|
||||
// Returns a list of all the mods that the current project depends on
|
||||
private static List<FabricModJson> getDependentMods(DeobfProjectView projectView, AsyncCache<List<FabricModJson>> fmjCache) {
|
||||
var futures = new ArrayList<CompletableFuture<List<FabricModJson>>>();
|
||||
Set<File> artifacts = projectView.getFullClasspath().getFiles();
|
||||
|
||||
for (File artifact : artifacts) {
|
||||
for (File artifact : projectView.getFullClasspath().getFiles()) {
|
||||
futures.add(fmjCache.get(artifact.toPath().toAbsolutePath().toString(), () -> {
|
||||
return getMod(artifact.toPath())
|
||||
.map(List::of)
|
||||
@@ -128,21 +150,21 @@ public record DeobfSpecContext(List<FabricModJson> modDependencies,
|
||||
return SpecContext.distinctSorted(AsyncCache.joinList(futures));
|
||||
}
|
||||
|
||||
// Returns a list of mod ids in a given configuration
|
||||
private static Set<String> getModIds(FileCollection configuration, AsyncCache<List<FabricModJson>> fmjCache) {
|
||||
// Returns a list of mods from a given configuration
|
||||
private static List<FabricModJson> getModsFromConfiguration(FileCollection configuration, AsyncCache<List<FabricModJson>> fmjCache) {
|
||||
var futures = new ArrayList<CompletableFuture<List<FabricModJson>>>();
|
||||
|
||||
Set<File> artifacts = configuration.getFiles();
|
||||
|
||||
for (File artifact : artifacts) {
|
||||
futures.add(fmjCache.get(artifact.toPath().toAbsolutePath().toString(), () -> {
|
||||
return getMod(artifact.toPath())
|
||||
.map(List::of)
|
||||
.orElseGet(List::of);
|
||||
}));
|
||||
for (File artifact : configuration.getFiles()) {
|
||||
futures.add(fmjCache.get(artifact.toPath().toAbsolutePath().toString(), () -> getMod(artifact.toPath())
|
||||
.map(List::of)
|
||||
.orElseGet(List::of)));
|
||||
}
|
||||
|
||||
return SpecContext.distinctSorted(AsyncCache.joinList(futures)).stream()
|
||||
return SpecContext.distinctSorted(AsyncCache.joinList(futures));
|
||||
}
|
||||
|
||||
private static Set<String> toModIdSet(List<FabricModJson> mods) {
|
||||
return mods.stream()
|
||||
.map(FabricModJson::getId)
|
||||
.collect(HashSet::new, Set::add, Set::addAll);
|
||||
}
|
||||
@@ -170,9 +192,7 @@ public record DeobfSpecContext(List<FabricModJson> modDependencies,
|
||||
var mods = new ArrayList<FabricModJson>();
|
||||
|
||||
for (Project dependentProject : getCompileRuntimeProjectDependencies(projectView).toList()) {
|
||||
List<FabricModJson> projectMods = fmjCache.getBlocking(dependentProject.getPath(), () -> {
|
||||
return FabricModJsonHelpers.getModsInProject(dependentProject);
|
||||
});
|
||||
List<FabricModJson> projectMods = fmjCache.getBlocking(dependentProject.getPath(), () -> FabricModJsonHelpers.getModsInProject(dependentProject));
|
||||
|
||||
mods.addAll(projectMods);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ import net.fabricmc.loom.util.gradle.GradleUtils;
|
||||
|
||||
// Used to abstract out the Gradle API usage to ease unit testing.
|
||||
public interface ProjectView {
|
||||
// Returns a list of Loom Projects found in the specified Configuration
|
||||
//Returns a list of Loom Projects found in the specified Configuration
|
||||
Stream<Project> getLoomProjectDependencies(String name);
|
||||
|
||||
// Returns the mods defined in the current project
|
||||
|
||||
Reference in New Issue
Block a user