added buffering to boost performance
This commit is contained in:
@@ -30,7 +30,7 @@ public class Main {
|
||||
|
||||
@SneakyThrows
|
||||
private static InputStream extractTestData() {
|
||||
return new XZInputStream(new BufferedInputStream(Main.class.getResourceAsStream("/citylots.json.xz")));
|
||||
return new XZInputStream(Main.class.getResourceAsStream("/citylots.json.xz"));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@@ -62,7 +62,7 @@ public class Main {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
chr.reset();
|
||||
for (int i = 0; i < loops; i++) {
|
||||
Value value = new JSONParser().parse(smallTestData());
|
||||
Value value = new JSONParser().parse(new BufferedReader(new InputStreamReader(smallTestData())));
|
||||
}
|
||||
}
|
||||
worthTime = chr.stop(Chronometer.TimeUnit.MILLISECOND);
|
||||
@@ -98,7 +98,7 @@ public class Main {
|
||||
try (InputStream is = extractTestData()) {
|
||||
chr.reset();
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.readTree(is);
|
||||
om.readTree(new InputStreamReader(is));
|
||||
double elapsedTime = chr.stop(Chronometer.TimeUnit.SECOND);
|
||||
System.out.printf("Jackson time: %8s sec\n", String.format("%.3f", elapsedTime));
|
||||
}
|
||||
|
@@ -8,7 +8,11 @@ import java.io.Reader;
|
||||
public class LookAheadTextInputStream extends InputStream {
|
||||
|
||||
private final Reader reader;
|
||||
private int currentByte;
|
||||
private char[] buffer = new char[1024];
|
||||
private int bufferFill = -1;
|
||||
private int cursor = -1;
|
||||
private int currentChar;
|
||||
|
||||
|
||||
public LookAheadTextInputStream(Reader reader) {
|
||||
this.reader = reader;
|
||||
@@ -17,12 +21,21 @@ public class LookAheadTextInputStream extends InputStream {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public int read() {
|
||||
int result = currentByte;
|
||||
currentByte = reader.read();
|
||||
return result;
|
||||
if (cursor > bufferFill) {
|
||||
return -1;
|
||||
} else if (cursor == bufferFill) {
|
||||
do {
|
||||
bufferFill = reader.read(buffer, 0, buffer.length) - 1;
|
||||
cursor = 0;
|
||||
} while(bufferFill == -1);
|
||||
currentChar = bufferFill == -2 ? -1 : buffer[0];
|
||||
} else {
|
||||
currentChar = buffer[++cursor];
|
||||
}
|
||||
return currentChar;
|
||||
}
|
||||
|
||||
public int getCurrentByte(){
|
||||
return currentByte;
|
||||
public int getCurrentByte() {
|
||||
return currentChar;
|
||||
}
|
||||
}
|
||||
|
@@ -27,10 +27,10 @@ public class JSONParser extends ValueParser {
|
||||
return c >= '0' && c <= '9' || c == '+' || c == '-' || c == '.' || c == 'e';
|
||||
}
|
||||
|
||||
private static int parseHex(LookAheadTextInputStream stream) {
|
||||
static int parseHex(LookAheadTextInputStream stream) {
|
||||
int result = 0;
|
||||
while (true) {
|
||||
int c = stream.getCurrentByte();
|
||||
int c = stream.getCurrentByte();
|
||||
while (c != -1) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
result = result << 4;
|
||||
result += (c - '0');
|
||||
@@ -43,7 +43,7 @@ public class JSONParser extends ValueParser {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
stream.read();
|
||||
c = stream.read();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -64,19 +64,19 @@ public class JSONParser extends ValueParser {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private final int parseId(LookAheadTextInputStream stream) {
|
||||
private int parseId(LookAheadTextInputStream stream) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean digitsStarted = false;
|
||||
boolean digitsEnded = false;
|
||||
while (true) {
|
||||
int b = stream.getCurrentByte();
|
||||
if(b == '(' ) {
|
||||
} else if(Character.isWhitespace(b)) {
|
||||
if(digitsStarted) digitsEnded = true;
|
||||
if (b == '(') {
|
||||
} else if (Character.isWhitespace(b)) {
|
||||
if (digitsStarted) digitsEnded = true;
|
||||
} else if (b < 0 || b == ')') {
|
||||
break;
|
||||
} else if (isDecimal(b)) {
|
||||
if(digitsEnded) {
|
||||
if (digitsEnded) {
|
||||
error(ParseException::new, "error parsing id");
|
||||
} else {
|
||||
digitsStarted = true;
|
||||
@@ -85,7 +85,7 @@ public class JSONParser extends ValueParser {
|
||||
}
|
||||
stream.read();
|
||||
}
|
||||
return Integer.valueOf(sb.toString());
|
||||
return Integer.parseInt(sb.toString());
|
||||
}
|
||||
|
||||
private String readString(LookAheadTextInputStream stream) {
|
||||
@@ -151,14 +151,15 @@ public class JSONParser extends ValueParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T extends RuntimeException> T error(Function<String, T> constructor, String fmt, Object ...args) {
|
||||
protected <T extends RuntimeException> T error(Function<String, T> constructor, String fmt, Object... args) {
|
||||
return constructor.apply(String.format("Error at line %d column %d: %s",
|
||||
currentLine, currentColumn, String.format(fmt, args)));
|
||||
currentLine, currentColumn, String.format(fmt, args)));
|
||||
}
|
||||
|
||||
public static Parser newInstance() {
|
||||
return new JSONParser();
|
||||
}
|
||||
|
||||
public static Parser newInstance(Value.Configuration cfg) {
|
||||
return new JSONParser(cfg);
|
||||
}
|
||||
@@ -192,6 +193,7 @@ public class JSONParser extends ValueParser {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
stream.read();
|
||||
|
||||
try {
|
||||
Integer currentId = null;
|
||||
@@ -204,13 +206,13 @@ public class JSONParser extends ValueParser {
|
||||
currentId = parseId(stream);
|
||||
} else if (c == '{') {
|
||||
Value newObject = beginObject();
|
||||
if(currentId != null) valueId(currentId, newObject);
|
||||
if (currentId != null) valueId(currentId, newObject);
|
||||
currentId = null;
|
||||
} else if (c == '}') {
|
||||
endObject();
|
||||
} else if (c == '[') {
|
||||
Value newArray = beginArray();
|
||||
if(currentId != null) valueId(currentId, newArray);
|
||||
if (currentId != null) valueId(currentId, newArray);
|
||||
currentId = null;
|
||||
} else if (c == ']') {
|
||||
endArray();
|
||||
@@ -246,7 +248,7 @@ public class JSONParser extends ValueParser {
|
||||
} else if (idMap != null && c == '$') {
|
||||
stream.read();
|
||||
String text = parseNumber(stream);
|
||||
valueReference(Integer.valueOf(text));
|
||||
valueReference(Integer.parseInt(text));
|
||||
continue;
|
||||
}
|
||||
stream.read();
|
||||
@@ -262,7 +264,7 @@ public class JSONParser extends ValueParser {
|
||||
}
|
||||
throw error(ParseException::new, "Missing '%c' token", c);
|
||||
}
|
||||
return WorthUtils.dynamicCast(stack.getFirst(), ArrayStackLevel.class).value.get(0);
|
||||
return ((ArrayStackLevel) stack.getFirst()).value.get(0);
|
||||
} catch (NumberFormatException e) {
|
||||
throw error(ParseException::new, e.getMessage());
|
||||
} finally {
|
||||
|
@@ -79,18 +79,4 @@ public class JBONTest {
|
||||
Assert.assertEquals(originalValue, binarySerializedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void hexTest() {
|
||||
String hex = "1F608";
|
||||
byte[] buffer = hex.getBytes();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
|
||||
Method method = JSONParser.class.getDeclaredMethod("parseHex", LookAheadTextInputStream.class);
|
||||
method.setAccessible(true);
|
||||
LookAheadTextInputStream ltis = new LookAheadTextInputStream(new InputStreamReader(bais));
|
||||
ltis.read();
|
||||
int result = (int) method.invoke(null, ltis);
|
||||
Assert.assertEquals((int) Integer.valueOf(hex, 16), result);
|
||||
}
|
||||
}
|
||||
|
@@ -228,11 +228,9 @@ public class JSONTest {
|
||||
String hex = "1F608";
|
||||
byte[] buffer = hex.getBytes();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
|
||||
Method method = JSONParser.class.getDeclaredMethod("parseHex", LookAheadTextInputStream.class);
|
||||
method.setAccessible(true);
|
||||
LookAheadTextInputStream ltis = new LookAheadTextInputStream(new InputStreamReader(bais));
|
||||
ltis.read();
|
||||
int result = (int) method.invoke(null, ltis);
|
||||
Assert.assertEquals((int) Integer.valueOf(hex, 16), result);
|
||||
int result = JSONParser.parseHex(ltis);
|
||||
Assert.assertEquals(Integer.parseInt(hex, 16), result);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user