Skip to content

Commit 3cc00af

Browse files
committed
Minor Reader optimisations
1 parent ec5056d commit 3cc00af

File tree

6 files changed

+104
-49
lines changed

6 files changed

+104
-49
lines changed

convex-core/src/main/java/convex/core/data/Cells.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import java.io.IOException;
44
import java.lang.reflect.Array;
5+
import java.util.Collection;
56
import java.util.function.Consumer;
67

78
import convex.core.Result;
89
import convex.core.exceptions.ParseException;
910
import convex.core.store.AStore;
1011
import convex.core.store.Stores;
12+
import convex.core.util.Utils;
1113

1214
/**
1315
* Static utility class for dealing with cells
@@ -39,19 +41,39 @@ public static boolean equals(ACell a, ACell b) {
3941
}
4042

4143
/**
42-
* Converts any array to an ACell[] array. Elements must be Cells.
44+
* Converts any collection object to an ACell[] array. Elements must be Cells.
4345
*
4446
* @param anyArray Array to convert
4547
* @return ACell[] array
4648
*/
47-
public static ACell[] toCellArray(Object anyArray) {
48-
int n = Array.getLength(anyArray);
49-
ACell[] result = new ACell[n];
50-
for (int i = 0; i < n; i++) {
51-
result[i] = (ACell) Array.get(anyArray, i);
49+
@SuppressWarnings("unchecked")
50+
public static ACell[] toCellArray(Object any) {
51+
if (any instanceof Collection) {
52+
return toCellArray((Collection<ACell>)any);
53+
} else if (any.getClass().isArray()) {
54+
int n = Array.getLength(any);
55+
ACell[] result = new ACell[n];
56+
for (int i = 0; i < n; i++) {
57+
result[i] = (ACell) Array.get(any, i);
58+
}
59+
return result;
60+
} else {
61+
throw new IllegalArgumentException("Can't get cell array from "+Utils.getClassName(any));
5262
}
53-
return result;
5463
}
64+
65+
/**
66+
* Converts any array to an ACell[] array. Elements must be Cells.
67+
*
68+
* @param coll Array to convert
69+
* @return ACell[] array
70+
*/
71+
public static ACell[] toCellArray(Collection<? extends ACell> coll) {
72+
int n=coll.size();
73+
if (n==0) return Cells.EMPTY_ARRAY;
74+
return coll.toArray(new ACell[n]);
75+
}
76+
5577

5678
/**
5779
* Gets the number of Refs directly contained in a Cell (will be zero if the

convex-core/src/main/java/convex/core/data/Lists.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public static <T extends ACell> List<T> empty() {
99

1010
@SuppressWarnings("unchecked")
1111
public static <T extends ACell, L extends AList<T>> L create(java.util.List<T> list) {
12-
return (L) List.of(list.toArray());
12+
return (L) List.create(Cells.toCellArray(list));
1313
}
1414

1515
@SafeVarargs

convex-core/src/main/java/convex/core/data/Vectors.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ public static <T extends ACell> AVector<T> wrap(ACell[] elements) {
8686
* @return New vector with the specified collection of elements
8787
*/
8888
@SuppressWarnings("unchecked")
89-
public static <R extends ACell, T extends ACell> AVector<R> create(Collection<?> elements) {
89+
public static <R extends ACell, T extends ACell> AVector<R> create(Collection<? extends ACell> elements) {
9090
if (elements instanceof ASequence) return ((ASequence<R>) elements).toVector();
91-
if (elements.size() == 0) return empty();
92-
ACell[] cells=Cells.toCellArray(elements.toArray());
91+
if (elements.isEmpty()) return empty();
92+
ACell[] cells=Cells.toCellArray(elements);
9393
return wrap(cells);
9494
}
9595

convex-core/src/main/java/convex/core/data/prim/AInteger.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public static AInteger parse(String s) {
4747
if (n<19) return CVMLong.parse(s); // can't be a big integer
4848
if (n>20) return CVMBigInteger.parse(s); // can't be a long
4949

50+
// Try long first, otherwise fall back to big integer
5051
AInteger r= CVMLong.parse(s);
5152
if (r==null) {
5253
r=CVMBigInteger.parse(s);

convex-core/src/main/java/convex/core/lang/reader/AntlrReader.java

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package convex.core.lang.reader;
22

33
import java.io.IOException;
4-
import java.lang.reflect.InvocationTargetException;
5-
import java.lang.reflect.Method;
64
import java.util.ArrayList;
75

86
import org.antlr.v4.runtime.CharStream;
@@ -41,7 +39,38 @@
4139
import convex.core.lang.reader.antlr.ConvexLexer;
4240
import convex.core.lang.reader.antlr.ConvexListener;
4341
import convex.core.lang.reader.antlr.ConvexParser;
44-
import convex.core.lang.reader.antlr.ConvexParser.*;
42+
import convex.core.lang.reader.antlr.ConvexParser.AddressContext;
43+
import convex.core.lang.reader.antlr.ConvexParser.AllFormsContext;
44+
import convex.core.lang.reader.antlr.ConvexParser.AtomContext;
45+
import convex.core.lang.reader.antlr.ConvexParser.BlobContext;
46+
import convex.core.lang.reader.antlr.ConvexParser.BoolContext;
47+
import convex.core.lang.reader.antlr.ConvexParser.CharacterContext;
48+
import convex.core.lang.reader.antlr.ConvexParser.CommentedContext;
49+
import convex.core.lang.reader.antlr.ConvexParser.DataStructureContext;
50+
import convex.core.lang.reader.antlr.ConvexParser.DoubleValueContext;
51+
import convex.core.lang.reader.antlr.ConvexParser.FormContext;
52+
import convex.core.lang.reader.antlr.ConvexParser.FormsContext;
53+
import convex.core.lang.reader.antlr.ConvexParser.ImplicitSymbolContext;
54+
import convex.core.lang.reader.antlr.ConvexParser.KeywordContext;
55+
import convex.core.lang.reader.antlr.ConvexParser.ListContext;
56+
import convex.core.lang.reader.antlr.ConvexParser.LiteralContext;
57+
import convex.core.lang.reader.antlr.ConvexParser.LongValueContext;
58+
import convex.core.lang.reader.antlr.ConvexParser.MapContext;
59+
import convex.core.lang.reader.antlr.ConvexParser.NilContext;
60+
import convex.core.lang.reader.antlr.ConvexParser.PathSymbolContext;
61+
import convex.core.lang.reader.antlr.ConvexParser.PrimaryContext;
62+
import convex.core.lang.reader.antlr.ConvexParser.QuotedContext;
63+
import convex.core.lang.reader.antlr.ConvexParser.ResolveContext;
64+
import convex.core.lang.reader.antlr.ConvexParser.SetContext;
65+
import convex.core.lang.reader.antlr.ConvexParser.SingleFormContext;
66+
import convex.core.lang.reader.antlr.ConvexParser.SlashSymbolContext;
67+
import convex.core.lang.reader.antlr.ConvexParser.SpecialLiteralContext;
68+
import convex.core.lang.reader.antlr.ConvexParser.StringContext;
69+
import convex.core.lang.reader.antlr.ConvexParser.SymbolContext;
70+
import convex.core.lang.reader.antlr.ConvexParser.SyntaxContext;
71+
import convex.core.lang.reader.antlr.ConvexParser.TagContext;
72+
import convex.core.lang.reader.antlr.ConvexParser.TaggedFormContext;
73+
import convex.core.lang.reader.antlr.ConvexParser.VectorContext;
4574
import convex.core.util.Utils;
4675

4776
public class AntlrReader {
@@ -58,18 +87,14 @@ public CRListener() {
5887
* @param a
5988
*/
6089
public void push(ACell a) {
61-
int n=stack.size()-1;
62-
ArrayList<ACell> top=stack.get(n);
90+
ArrayList<ACell> top=stack.getLast();
6391
top.add(a);
6492
}
6593

6694
@SuppressWarnings("unchecked")
6795
public <R extends ACell> R pop() {
68-
int n=stack.size()-1;
69-
ArrayList<ACell> top=stack.get(n);
70-
int c=top.size()-1;
71-
ACell cell=top.get(c);
72-
top.remove(c);
96+
ArrayList<ACell> top=stack.getLast();
97+
ACell cell=top.removeLast();
7398
return (R) cell;
7499
}
75100

@@ -79,9 +104,7 @@ private void pushList() {
79104
}
80105

81106
public ArrayList<ACell> popList() {
82-
int n=stack.size()-1;
83-
ArrayList<ACell> top=stack.get(n);
84-
stack.remove(n);
107+
ArrayList<ACell> top=stack.removeLast();
85108
return top;
86109
}
87110

@@ -178,7 +201,7 @@ public void enterMap(MapContext ctx) {
178201
public void exitMap(MapContext ctx) {
179202
ArrayList<ACell> elements=popList();
180203
if (Utils.isOdd(elements.size())) {
181-
throw new ParseException("Map requires an even number form forms.");
204+
throw new ParseException("Map requires an even number of forms.");
182205
}
183206
push(Maps.create(elements.toArray(new ACell[elements.size()])));
184207
}
@@ -200,7 +223,8 @@ public void enterLongValue(LongValueContext ctx) {
200223

201224
@Override
202225
public void exitLongValue(LongValueContext ctx) {
203-
String s=ctx.getText();
226+
// Just looking at the last token probably most efficient way to get string?
227+
String s=ctx.getStop().getText();
204228
AInteger a= AInteger.parse(s);
205229
if (a==null) throw new ParseException("Unparseable number: "+s);
206230
push(a);
@@ -246,7 +270,7 @@ public void enterCharacter(CharacterContext ctx) {
246270

247271
@Override
248272
public void exitCharacter(CharacterContext ctx) {
249-
String s=ctx.getText();
273+
String s=ctx.getStop().getText();
250274
CVMChar c=CVMChar.parse(s);
251275
if (c==null) throw new ParseException("Bad character literal format: "+s);
252276
push(c);
@@ -329,9 +353,14 @@ public void enterAddress(AddressContext ctx) {
329353
@Override
330354
public void exitAddress(AddressContext ctx) {
331355
String s=ctx.getStop().getText();
332-
Address addr=Address.parse(s);
333-
if (addr==null) throw new ParseException("Bad Address format: "+s);
334-
push (addr);
356+
try {
357+
long value=Long.parseLong(s.substring(1));
358+
Address addr=Address.create(value);
359+
if (addr==null) throw new ParseException("Bad Address format: "+s);
360+
push (addr);
361+
} catch (NumberFormatException e) {
362+
throw new ParseException("Problem parsing Address: "+s,e);
363+
}
335364
}
336365

337366
@Override
@@ -385,7 +414,7 @@ public void enterResolve(ResolveContext ctx) {
385414

386415
@Override
387416
public void exitResolve(ResolveContext ctx) {
388-
String s=ctx.getText();
417+
String s=ctx.getStop().getText();
389418
s=s.substring(1); // skip leading @
390419
Symbol sym=Symbol.create(s);
391420
if (sym==null) throw new ParseException("Invalid @ symbol: @"+s);
@@ -400,7 +429,7 @@ public void enterSlashSymbol(SlashSymbolContext ctx) {
400429

401430
@Override
402431
public void exitSlashSymbol(SlashSymbolContext ctx) {
403-
String s=ctx.getText();
432+
String s=ctx.getStop().getText();
404433
s=s.substring(1); // skip leading /
405434
Symbol sym=Symbol.create(s);
406435
if (sym==null) throw new ParseException("Invalid / symbol: /"+s);
@@ -465,7 +494,7 @@ public void exitPathSymbol(PathSymbolContext ctx) {
465494

466495
if (!(sym instanceof Symbol)) throw new ParseException("Expected path element to be a symbol but got: "+ RT.getType(sym));
467496
// System.out.println(elements);
468-
lookup=Lists.of(Symbols.LOOKUP,lookup,sym);
497+
lookup=List.create(Symbols.LOOKUP,lookup,sym);
469498
}
470499
push(lookup);
471500
}
@@ -537,14 +566,12 @@ static ACell read(CharStream cs) {
537566
// We don't need a parse tree, just want to visit everything in our listener
538567
parser.setBuildParseTree(false);
539568
parser.removeErrorListeners();
540-
parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
569+
parser.getInterpreter().setPredictionMode(PredictionMode.SLL); // Seems OK for our grammar?
541570
parser.addErrorListener(ERROR_LISTENER);
542571
CRListener visitor=new CRListener();
543572
parser.addParseListener(visitor);
544573

545-
// ParseTree tree = parser.singleForm();
546-
Method startRule = parser.getClass().getMethod("singleForm");
547-
startRule.invoke(parser, (Object[]) null);
574+
parser.singleForm();
548575
// ParseTreeWalker.DEFAULT.walk(visitor, tree);
549576

550577
ArrayList<ACell> top=visitor.popList();
@@ -553,8 +580,8 @@ static ACell read(CharStream cs) {
553580
}
554581

555582
return top.get(0);
556-
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
557-
throw new ParseException("Missing parse method",e);
583+
} catch (Exception e) {
584+
throw new ParseException("Unexpected Parse Error",e);
558585
}
559586
}
560587

convex-core/src/test/java/convex/core/examples/ReaderTrials.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,40 @@
77
import convex.core.init.Init;
88
import convex.core.lang.RT;
99
import convex.core.lang.Reader;
10+
import convex.core.text.Text;
1011
import convex.test.Samples;
1112

1213
/**
1314
* Test class for juice costs relative to execution time
1415
*/
1516
public class ReaderTrials {
1617

18+
// Data file (printout of a genesis CVM state)
1719
static State s=Init.createState(List.of(Samples.KEY_PAIR.getAccountKey()));
1820
static String data=RT.print(s,10000000).toString();
19-
static int len=data.length();
2021

2122
public static void main(String[] args) {
22-
System.out.println("Data Length: " + len);
23-
runTrial();
24-
runTrial();
25-
runTrial();
23+
runTrial("[1 2 3]",1000);
24+
runTrial("[1 2 3]",1000);
25+
runTrial("[1 2 3]",1000);
26+
27+
runTrial(data,10);
28+
runTrial(data,10);
29+
runTrial(data,10);
2630
}
2731

2832
@SuppressWarnings("unused")
29-
private static void runTrial() {
30-
long REPS=10;
31-
long start=System.currentTimeMillis();
33+
private static void runTrial(String data, long REPS) {
34+
int len=data.length();
35+
long start=System.nanoTime();
3236
ACell warmUp=readStuff(data);
3337
for (int i=0; i<REPS; i++) {
3438
ACell v=readStuff(data);
3539
}
36-
long end=System.currentTimeMillis();
40+
long end=System.nanoTime();
3741

38-
System.out.println((REPS*len)/(0.001*(end-start)));
42+
double bps=(REPS*len)/(0.000000001*(end-start));
43+
System.out.println("bytes/s: " +Text.toFriendlyNumber((long)bps));
3944
}
4045

4146
private static ACell readStuff(String data) {

0 commit comments

Comments
 (0)