我目前正试图用Java编写Brainfuck解释器。我试图通过删除注释和冗余代码来优化Brainfuck代码(为此我使用regex )。但是,我的未优化代码比优化的代码快几毫秒,我认为这是不可能的,因为我只是计时Brainfuck代码的执行时间。
以下是Brainfuck解释器本身(ReducedIntStack基本上是堆栈的自我实现):
package io.github.setvizan.brainfuck;
import io.github.setvizan.utils.ReducedIntStack;
public class Interpreter {
private static final int MAX_LENGTH = 65535;
private final int[] jmp = new int[MAX_LENGTH];
private final int[] arr = new int[MAX_LENGTH];
private int ptr = 0;
public static void interpret(String c) {
char[] commands = c.toCharArray();
Interpreter interpreter = new Interpreter();
interpreter.preloadJumpTable(commands);
interpreter.run(commands);
}
private void run(char[] commands) {
for (int i = -1, size = commands.length; ++i < size; ) {
switch (commands[i]) {
case '+':
arr[ptr]++;
break;
case '-':
arr[ptr]--;
break;
case '<':
if (ptr != 0) ptr--;
break;
case '>':
ptr++;
break;
case '[':
if (arr[ptr] == 0) i = jmp[i];
break;
case ']':
if (arr[ptr] != 0) i = jmp[i];
break;
case '.':
System.out.print((char) arr[ptr]);
break;
}
}
}
private void preloadJumpTable(char[] commands) {
ReducedIntStack stk = new ReducedIntStack(MAX_LENGTH);
for (int i = -1; ++i < commands.length; ) {
if (commands[i] == '[') {
stk.push(i);
} else if (commands[i] == ']') {
jmp[i] = stk.pop();
jmp[jmp[i]] = i;
}
}
}
}优化类:
package io.github.setvizan.brainfuck;
import java.util.regex.Pattern;
public class Optimizer {
private static final Pattern ENDLESS_LOOP_PATTERN = Pattern.compile("\\[\\]");
private static final Pattern INCREMENT_DECREMENT_PATTERN = Pattern.compile("\\+-|-\\+");
private static final Pattern FORWARD_BACKWARD_PATTERN = Pattern.compile("><|<>");
private static final Pattern REMOVE_USELESS_CHARACTERS = Pattern.compile("[^<>\\.,\\[\\]\\+-]");
public static String apply(String in) {
String optimized = in;
optimized = removeUselessCharacters(optimized);
optimized = removeEndlessLoops(optimized);
optimized = removeForwardBackwards(optimized);
optimized = removeIncrementDecrements(optimized);
return optimized;
}
private static String removeEndlessLoops(String input) {
return ENDLESS_LOOP_PATTERN.matcher(input).replaceAll("");
}
private static String removeIncrementDecrements(String input) {
return INCREMENT_DECREMENT_PATTERN.matcher(input).replaceAll("");
}
private static String removeForwardBackwards(String input) {
return FORWARD_BACKWARD_PATTERN.matcher(input).replaceAll("");
}
private static String removeUselessCharacters(String input) {
return REMOVE_USELESS_CHARACTERS.matcher(input).replaceAll("");
}
}这就是我如何在Java中计时我的代码:
public static void run(String file, boolean optimize){
File bfFile = new File(file);
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(bfFile));
String source = bufferedReader.lines().collect(Collectors.joining());
if (optimize) source = Optimizer.apply(source);
long t1 = System.nanoTime();
Interpreter.interpret(source);
long t2 = System.nanoTime();
System.out.println("\n"+(t2 - t1) + "ns - this program was optimized? "+optimize);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}我试图获取一个包含大量注释的文件,比如(在Brainfuck中没有使用的4000个符号和在Brainfuck中使用的400个符号),而未优化的脚本仍然运行得更快。
我还检查了Brainfuck解释器是否真的不会在需要时运行优化版本。
我制作了一个运行Java 100次的脚本,而未优化的脚本运行速度快了整整一秒钟。
发布于 2022-10-27 15:18:02
结果就像“扫地者”说的,我没有正确地写出我的基准。
在建立JMH并学习如何使用它之后。
结果表明,优化后的代码运行速度约为0.4ms。
https://stackoverflow.com/questions/74222331
复制相似问题