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

Greatly improve Java bf2 performance #175

Closed
wants to merge 1 commit 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
64 changes: 31 additions & 33 deletions brainfuck2/bf.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,43 @@
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class bf {
public final class bf {

public enum OpT {INC, MOVE, PRINT, LOOP}

public static class Op {
public OpT op;
public int v;
public List<Op> loop;
public static final class Op {
private static final Op[] NO_LOOP_OPS = new Op[0];

public Op(OpT _op, int _v) { op = _op; v = _v; loop = new ArrayList<Op>(); }
public Op(OpT _op, List<Op> _l) { op = _op; loop = _l; v = 0; }
public final OpT op;
public final int v;
public final Op[] loop;

public Op(final OpT _op, final int _v) { op = _op; v = _v; loop = NO_LOOP_OPS; }
public Op(final OpT _op, final Op[] _l) { op = _op; loop = _l; v = 0; }
}

public static class CharacterIterator {
public static final class CharacterIterator {
private final String str;
private final int strLen;
private int pos = 0;

public CharacterIterator(String str) {
public CharacterIterator(final String str) {
this.str = str;
strLen = str.length();
}

public boolean hasNext() {
return pos < str.length();
return pos < strLen;
}

public Character next() {
public char next() {
return str.charAt(pos++);
}
}

public static class Tape {
public static final class Tape {
private int[] tape;
private int pos;

Expand All @@ -49,31 +50,30 @@ public int get() {
return tape[pos];
}

public void inc(int x) {
public void inc(final int x) {
tape[pos] += x;
}

public void move(int x) {
public void move(final int x) {
pos += x;
while ( pos >= tape.length ) {
int[] tape = new int[this.tape.length * 2];
final int[] tape = new int[this.tape.length * 2];
System.arraycopy( this.tape, 0, tape, 0, this.tape.length );
this.tape = tape;
}

}
}

public static class Program {
private List<Op> ops;
public static final class Program {
private final Op[] ops;

public Program(String code) {
public Program(final String code) {
CharacterIterator it = new CharacterIterator(code);
ops = parse(it);
}

private List<Op> parse(CharacterIterator it) {
List<Op> res = new ArrayList<Op>();
private Op[] parse(final CharacterIterator it) {
final List<Op> res = new ArrayList<>();
while (it.hasNext()) {
switch( it.next() ) {
case '+':
Expand All @@ -95,30 +95,29 @@ private List<Op> parse(CharacterIterator it) {
res.add(new Op(OpT.LOOP, parse(it)));
break;
case ']':
return res;
return res.toArray(new Op[res.size()]);
}
}
return res;
return res.toArray(new Op[res.size()]);
}

public void run() {
_run(ops, new Tape());
}

private void _run(List<Op> program, Tape tape) {
for (Op op : program) {
private void _run(final Op[] program, final Tape tape) {
for (final Op op : program)
switch (op.op) {
case INC: tape.inc(op.v); break;
case MOVE: tape.move(op.v); break;
case LOOP: while (tape.get() > 0) _run(op.loop, tape); break;
case PRINT: System.out.print( (char) tape.get() ); break;
}
}
}
}

public static void main( String[] args ) throws IOException {
byte[] code = Files.readAllBytes( Paths.get( args[0] ) );
public static void main( final String[] args ) throws IOException {
final byte[] code = Files.readAllBytes( Paths.get( args[0] ) );

long start_time = System.currentTimeMillis();
System.err.println("warming");
Expand All @@ -127,9 +126,8 @@ public static void main( String[] args ) throws IOException {

System.err.println("run");
start_time = System.currentTimeMillis();
Program program = new Program(new String(code));
final Program program = new Program(new String(code));
program.run();
System.err.println("time: " + (System.currentTimeMillis()-start_time)/1e3+"s");
}
}