perf: parallel translation
ci/woodpecker/push/jfmod Pipeline was successful Details

This commit is contained in:
Johannes Frohnmeyer 2023-10-05 16:46:41 +02:00
parent dfea11cafd
commit f82ded7e5d
Signed by: Johannes
GPG Key ID: E76429612C2929F4
5 changed files with 95 additions and 22 deletions

View File

@ -0,0 +1,25 @@
package io.gitlab.jfronny.translater;
import io.gitlab.jfronny.translater.mixin.MinecraftClientAccessor;
import net.minecraft.client.MinecraftClient;
import java.util.concurrent.atomic.AtomicBoolean;
public class RenderScheduler {
private final AtomicBoolean shouldRun = new AtomicBoolean(false);
public void scheduleRender() {
shouldRun.set(true);
if (MinecraftClient.getInstance().isOnThread()) performTask();
}
public void deschedule() {
shouldRun.set(false);
}
private void performTask() {
do {
((MinecraftClientAccessor) MinecraftClient.getInstance()).invokeRender(false);
} while (shouldRun.compareAndSet(true, false));
}
}

View File

@ -9,7 +9,10 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
public class CachingTransformer implements Transformer {
private static final Path CACHE_FILE = FabricLoader.getInstance().getConfigDir().resolve(Translater.MOD_ID + ".cache");
@ -36,6 +39,30 @@ public class CachingTransformer implements Transformer {
return (String) cache.get(str);
}
@Override
public void transformMultiple(Stream<? extends String> strings, ResultConsumer results) {
AtomicBoolean bl = new AtomicBoolean(false);
transformer.transformMultiple(strings.filter(s -> {
String translation = (String) cache.get(s);
if (translation != null) {
results.accept(s, translation);
return false;
}
if (defaultCache != null) {
translation = (String) defaultCache.get(s);
if (translation != null) {
results.accept(s, translation);
return false;
}
}
return true;
}), (str, translation) -> {
cache.put(str, translation);
bl.set(true);
});
if (bl.get()) save();
}
public CachingTransformer(Transformer baseTransformer) {
transformer = baseTransformer;
if (Cfg.forceRegenerate) {

View File

@ -1,5 +1,13 @@
package io.gitlab.jfronny.translater.transformer;
import java.util.stream.Stream;
public interface Transformer {
String transform(String str);
void transformMultiple(Stream<? extends String> strings, ResultConsumer results);
@FunctionalInterface
interface ResultConsumer {
void accept(String str, String translation);
}
}

View File

@ -1,5 +1,6 @@
package io.gitlab.jfronny.translater.transformer;
import io.gitlab.jfronny.translater.RenderScheduler;
import io.gitlab.jfronny.translater.Translater;
import io.gitlab.jfronny.translater.mixin.MinecraftClientAccessor;
import net.minecraft.client.MinecraftClient;
@ -7,12 +8,15 @@ import net.minecraft.client.MinecraftClient;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
public class TransformingMap implements Map<String, String> {
private final Transformer transformer;
private final RenderScheduler renderScheduler = new RenderScheduler();
private Map<String, String> backer = null;
public boolean initializing = false;
private String initProgress = null;
private AtomicInteger initProgress = null;
private int maxProgress = 0;
public TransformingMap(Transformer t) {
transformer = t;
@ -23,24 +27,26 @@ public class TransformingMap implements Map<String, String> {
this.backer = backer;
Collection<String> strings = backer.values();
initializing = true;
final int max = strings.size();
int i = 0;
for (String value : strings) {
initProgress = "Transforming " + i++ + "/" + max;
if (Translater.progressLogsEnabled())
Translater.LOGGER.info(initProgress);
if (Translater.progressUIEnabled() && i % 10 == 0)
((MinecraftClientAccessor) MinecraftClient.getInstance()).invokeRender(false);
initProgress = null;
transformer.transform(value);
}
generateTranslations(strings);
initializing = false;
}
}
private void generateTranslations(Collection<? extends String> strings) {
maxProgress = strings.size();
initProgress = new AtomicInteger();
transformer.transformMultiple(strings.parallelStream(), (str, translation) -> {
int i = initProgress.incrementAndGet();
if (Translater.progressLogsEnabled()) Translater.LOGGER.info(getInitProgress());
if (Translater.progressUIEnabled() && i % 10 == 0) renderScheduler.scheduleRender();
});
renderScheduler.deschedule();
initProgress = null;
}
public String getInitProgress() {
if (initProgress == null || !initializing) throw new IllegalStateException("Tried to get init progress while not initializing");
return initProgress;
return "Transforming " + initProgress.get() + "/" + maxProgress;
}
@Override
@ -65,8 +71,7 @@ public class TransformingMap implements Map<String, String> {
@Override
public String get(Object o) {
if (o instanceof String && ((String)o).startsWith("translater."))
return backer.get(o);
if (o instanceof String s && s.startsWith("translater.")) return backer.get(s);
return transformer.transform(backer.get(o));
}
@ -83,9 +88,7 @@ public class TransformingMap implements Map<String, String> {
@Override
public void putAll(Map<? extends String, ? extends String> map) {
for (String value : map.values()) {
transformer.transform(value);
}
generateTranslations(map.values());
backer.putAll(map);
}
@ -101,11 +104,11 @@ public class TransformingMap implements Map<String, String> {
@Override
public Collection<String> values() {
return backer.values();
return backer.values(); // This does not support updates, but I don't care
}
@Override
public Set<Entry<String, String>> entrySet() {
return backer.entrySet();
return backer.entrySet(); // This does not support updates, but I don't care
}
}

View File

@ -7,10 +7,10 @@ import io.gitlab.jfronny.translater.Cfg;
import io.gitlab.jfronny.translater.Translater;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Random;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class TranslatingTransformer<T extends Language> implements Transformer {
public TranslatingTransformer(TranslateService<T> ts) {
@ -77,6 +77,16 @@ public class TranslatingTransformer<T extends Language> implements Transformer {
}
}
@Override
public void transformMultiple(Stream<? extends String> strings, ResultConsumer results) {
strings.flatMap(s -> {
String translation = transform(s);
return translation == null ? Stream.empty() : Stream.of(new Translation(s, translation));
}).forEach(t -> results.accept(t.from, t.to));
}
private record Translation(String from, String to) {}
private String translateMultiple(String str) throws TranslateException {
Matcher m = SURROUNDING_SPACE_PATTERN.matcher(str);
if (!m.find()) {