Skip to content

Commit

Permalink
Merge pull request #886 from vdebergue/json-error-performance
Browse files Browse the repository at this point in the history
Improve performance of json lookups in case of errors
  • Loading branch information
mkurz authored Jun 4, 2023
2 parents 6b41113 + 57fc231 commit d53f724
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
35 changes: 35 additions & 0 deletions benchmarks/src/main/scala/play/api/libs/json/JsLookupBench.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
*/

package play.api.libs.json

import org.openjdk.jmh.annotations._

import java.util.concurrent.TimeUnit

@Warmup(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.Throughput))
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(
jvmArgsAppend =
Array("-Xmx350m", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:-BackgroundCompilation", "-XX:-TieredCompilation"),
value = 1
)
class JsLookupBench {
@Param(Array("1", "20", "100"))
var size: Int = _
private var jsObject: JsObject = _

@Setup def setup(): Unit = {
jsObject = JsObject(0.until(size).map(i => i.toString -> JsString(s"This is my content for index $i")))
}

@Benchmark
def goodLookup: Option[String] = (jsObject \ (size - 1).toString).asOpt[String]

@Benchmark
def badLookup: Option[String] = (jsObject \ (size + 1).toString).asOpt[String]
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
*/

package play.api.libs.json

import org.openjdk.jmh.annotations._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ case class JsLookup(result: JsLookupResult) extends AnyVal {
obj.underlying
.get(fieldName)
.map(JsDefined.apply)
.getOrElse(JsUndefined(s"'$fieldName' is undefined on object: $obj"))
.getOrElse(
JsUndefined(s"'$fieldName' is undefined on object. Available keys are ${obj.keys.mkString("'", "', '", "'")}")
)
case JsDefined(o) =>
JsUndefined(s"$o is not an object")
case undef => undef
Expand Down

0 comments on commit d53f724

Please sign in to comment.