Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize Bootstrap to pre build faster by using multiple threads #28

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions src/main/java/com/mojang/datafixers/DataFixerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -62,16 +63,36 @@ public DataFixer build(final Executor executor) {
final DataFixerUpper fixerUpper = new DataFixerUpper(new Int2ObjectAVLTreeMap<>(schemas), new ArrayList<>(globalList), new IntAVLTreeSet(fixerVersions));

executor.execute(() -> {
final List<Runnable> allTasks = new ArrayList<>();
final IntBidirectionalIterator iterator = fixerUpper.fixerVersions().iterator();
while (iterator.hasNext()) {
final int versionKey = iterator.nextInt();
final Schema schema = schemas.get(versionKey);
for (final String typeName: schema.types()) {
final Type<?> dataType = schema.getType(() -> typeName);
final TypeRewriteRule rule = fixerUpper.getRule(DataFixUtils.getVersion(versionKey), dataVersion);
dataType.rewrite(rule, DataFixerUpper.OPTIMIZATION_RULE);
allTasks.add(() -> {
final Type<?> dataType = schema.getType(() -> typeName);
final TypeRewriteRule rule = fixerUpper.getRule(DataFixUtils.getVersion(versionKey), dataVersion);
dataType.rewrite(rule, DataFixerUpper.OPTIMIZATION_RULE);
});
}
}

// Divide up into sets of tasks by number of CPU cores
// Some tasks are faster than others, randomize it to try to divide it more
final List<List<Runnable>> queueList = new ArrayList<>();
final int maxTasks = (int) Math.max(1, Math.floor(allTasks.size() / (float)Math.min(6, Runtime.getRuntime().availableProcessors()-2)));
Collections.shuffle(allTasks);
List<Runnable> current = new ArrayList<>();
queueList.add(current);
for (final Runnable task: allTasks) {
if (current.size() >= maxTasks) {
current = new ArrayList<>();
queueList.add(current);
}
current.add(task);
}

queueList.forEach(queue -> executor.execute(() -> queue.forEach(Runnable::run)));
});

return fixerUpper;
Expand Down