diff --git a/sjsonnet/src/sjsonnet/Materializer.scala b/sjsonnet/src/sjsonnet/Materializer.scala index 42a891bc..1fe40b6e 100644 --- a/sjsonnet/src/sjsonnet/Materializer.scala +++ b/sjsonnet/src/sjsonnet/Materializer.scala @@ -33,10 +33,7 @@ abstract class Materializer { case Val.False(_) => "false" case Val.Null(_) => "null" case Val.Num(_, _) => - val d = v.asDouble - val l = d.toLong - if (l.toDouble == d) java.lang.Long.toString(l) - else RenderUtils.renderDouble(d) + RenderUtils.renderDouble(v.asDouble) case _ => apply0(v, new sjsonnet.Renderer()).toString } } diff --git a/sjsonnet/src/sjsonnet/Renderer.scala b/sjsonnet/src/sjsonnet/Renderer.scala index 5f925330..54069186 100644 --- a/sjsonnet/src/sjsonnet/Renderer.scala +++ b/sjsonnet/src/sjsonnet/Renderer.scala @@ -268,12 +268,18 @@ final case class MaterializeJsonRenderer( object RenderUtils { + // Pre-cached string representations of small integers (0-255) + private val intStrCache: Array[String] = Array.tabulate(256)(_.toString) + /** * Custom rendering of Doubles used in rendering */ def renderDouble(d: Double): String = { - if (d.toLong == d) d.toLong.toString - else if (d % 1 == 0) { + val l = d.toLong + if (l.toDouble == d) { + if (l >= 0 && l < 256) intStrCache(l.toInt) + else l.toString + } else if (d % 1 == 0) { BigDecimal(d).setScale(0, BigDecimal.RoundingMode.HALF_EVEN).toBigInt.toString() } else d.toString }