Skip to content

Commit

Permalink
chore: performance optimisation in JsonParser
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronald Holshausen committed Jun 15, 2020
1 parent 6207985 commit a0f51c0
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.junit.Test

@CompileStatic
@Ignore
@SuppressWarnings('ExplicitCallToDivMethod')
class JsonPerformanceSpec {

private final Map<String, String> jsonFiles = [:]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package au.com.dius.pact.core.support

import au.com.dius.pact.core.support.Json.toJson
import au.com.dius.pact.core.support.json.JsonToken
import au.com.dius.pact.core.support.json.JsonValue
import com.google.gson.Gson
import com.google.gson.GsonBuilder
Expand Down Expand Up @@ -107,18 +108,18 @@ object Json {
}
}

private fun Char.toJsonValue() = JsonValue.StringValue(charArrayOf(this))
private fun Char.toJsonValue() = JsonValue.StringValue(JsonToken.StringValue(charArrayOf(this)))

private fun Boolean.toJsonValue() = if (this) JsonValue.True
else JsonValue.False

private fun String.toJsonValue() = JsonValue.StringValue(this.toCharArray())
private fun String.toJsonValue() = JsonValue.StringValue(JsonToken.StringValue(this.toCharArray()))

private fun Number.toJsonValue(): JsonValue = when (this) {
is Int -> JsonValue.Integer(this.toString().toCharArray())
is Long -> JsonValue.Integer(this.toString().toCharArray())
is BigInteger -> JsonValue.Integer(this.toString().toCharArray())
else -> JsonValue.Decimal(this.toString().toCharArray())
is Int -> JsonValue.Integer(JsonToken.Integer(this.toString().toCharArray()))
is Long -> JsonValue.Integer(JsonToken.Integer(this.toString().toCharArray()))
is BigInteger -> JsonValue.Integer(JsonToken.Integer(this.toString().toCharArray()))
else -> JsonValue.Decimal(JsonToken.Decimal(this.toString().toCharArray()))
}

fun jsonArray(list: List<Any?>) = toJson(list)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ class JsonLexer(val json: JsonSource) {
}

private fun consumeChars(predicate: (Char) -> Boolean): CharArray {
val array = ArrayList<Char>(1000)
val array = mutableListOf<Char>()
var next = json.peekNextChar()
while (next != null && predicate(next)) {
array.add(next)
Expand Down Expand Up @@ -365,9 +365,9 @@ object JsonParser {
val lexer = JsonLexer(json)
var token = nextTokenOrThrow(lexer)
val jsonValue = when (token) {
is JsonToken.Integer -> JsonValue.Integer(token.chars)
is JsonToken.Decimal -> JsonValue.Decimal(token.chars)
is JsonToken.StringValue -> JsonValue.StringValue(token.chars)
is JsonToken.Integer -> JsonValue.Integer(token)
is JsonToken.Decimal -> JsonValue.Decimal(token)
is JsonToken.StringValue -> JsonValue.StringValue(token)
is JsonToken.True -> JsonValue.True
is JsonToken.False -> JsonValue.False
is JsonToken.Null -> JsonValue.Null
Expand Down Expand Up @@ -421,9 +421,9 @@ object JsonParser {
when (token) {
null -> throw JsonException(
"Invalid Json document (${lexer.documentPointer()}) - found end of document while parsing object")
is JsonToken.Integer -> map[key] = JsonValue.Integer(token.chars)
is JsonToken.Decimal -> map[key] = JsonValue.Decimal(token.chars)
is JsonToken.StringValue -> map[key] = JsonValue.StringValue(token.chars)
is JsonToken.Integer -> map[key] = JsonValue.Integer(token)
is JsonToken.Decimal -> map[key] = JsonValue.Decimal(token)
is JsonToken.StringValue -> map[key] = JsonValue.StringValue(token)
is JsonToken.True -> map[key] = JsonValue.True
is JsonToken.False -> map[key] = JsonValue.False
is JsonToken.Null -> map[key] = JsonValue.Null
Expand Down Expand Up @@ -459,9 +459,9 @@ object JsonParser {
when (token) {
null -> throw JsonException(
"Invalid Json document (${lexer.documentPointer()}) - found end of document while parsing array")
is JsonToken.Integer -> array.add(JsonValue.Integer(token.chars))
is JsonToken.Decimal -> array.add(JsonValue.Decimal(token.chars))
is JsonToken.StringValue -> array.add(JsonValue.StringValue(token.chars))
is JsonToken.Integer -> array.add(JsonValue.Integer(token))
is JsonToken.Decimal -> array.add(JsonValue.Decimal(token))
is JsonToken.StringValue -> array.add(JsonValue.StringValue(token))
is JsonToken.True -> array.add(JsonValue.True)
is JsonToken.False -> array.add(JsonValue.False)
is JsonToken.Null -> array.add(JsonValue.Null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ import com.google.gson.JsonPrimitive
import org.apache.commons.lang3.StringEscapeUtils

sealed class JsonValue {
class Integer(val value: CharArray) : JsonValue() {
fun toBigInteger() = String(this.value).toBigInteger()
class Integer(val value: JsonToken.Integer) : JsonValue() {
constructor(value: CharArray) : this(JsonToken.Integer(value))
fun toBigInteger() = String(this.value.chars).toBigInteger()
}

class Decimal(val value: CharArray) : JsonValue() {
fun toBigDecimal() = String(this.value).toBigDecimal()
class Decimal(val value: JsonToken.Decimal) : JsonValue() {
constructor(value: CharArray) : this(JsonToken.Decimal(value))
fun toBigDecimal() = String(this.value.chars).toBigDecimal()
}

class StringValue(val value: CharArray) : JsonValue() {
override fun toString() = String(value)
class StringValue(val value: JsonToken.StringValue) : JsonValue() {
constructor(value: CharArray) : this(JsonToken.StringValue(value))
override fun toString() = String(value.chars)
}
object True : JsonValue()
object False : JsonValue()
Expand Down Expand Up @@ -79,7 +82,7 @@ sealed class JsonValue {

fun asString(): String {
return if (this is StringValue) {
String(value)
String(value.chars)
} else {
serialise()
}
Expand Down Expand Up @@ -111,8 +114,8 @@ sealed class JsonValue {
fun serialise(): String {
return when (this) {
is Null -> "null"
is Decimal -> String(this.value)
is Integer -> String(this.value)
is Decimal -> String(this.value.chars)
is Integer -> String(this.value.chars)
is StringValue -> "\"${StringEscapeUtils.escapeJson(this.asString())}\""
is True -> "true"
is False -> "false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import au.com.dius.pact.core.support.Json
import au.com.dius.pact.core.support.hasProperty
import au.com.dius.pact.core.support.isNotEmpty
import au.com.dius.pact.core.support.json.JsonParser
import au.com.dius.pact.core.support.json.JsonToken
import au.com.dius.pact.core.support.json.JsonValue
import au.com.dius.pact.core.support.jsonArray
import au.com.dius.pact.core.support.jsonObject
Expand Down Expand Up @@ -94,7 +95,7 @@ class JsonReporter(
"pending" to consumer.pending
)
if (tag.isNotEmpty()) {
jsonObject.add("tag", JsonValue.StringValue(tag!!.toCharArray()))
jsonObject.add("tag", JsonValue.StringValue(JsonToken.StringValue(tag!!.toCharArray())))
}
jsonData["execution"].add(jsonObject)
}
Expand Down Expand Up @@ -225,7 +226,7 @@ class JsonReporter(
verification["header"].asObject()[key] = when (comparison) {
is List<*> -> Json.toJson(comparison.map {
when (it) {
is HeaderMismatch -> JsonValue.StringValue(it.mismatch.toCharArray())
is HeaderMismatch -> JsonValue.StringValue(JsonToken.StringValue(it.mismatch.toCharArray()))
else -> Json.toJson(it)
}
})
Expand Down

0 comments on commit a0f51c0

Please sign in to comment.