From 0bc5a83b16b5fd92ca0307eedbe0cb558402dc47 Mon Sep 17 00:00:00 2001 From: kyri-petrou <67301607+kyri-petrou@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:28:37 +0200 Subject: [PATCH] Manually extract tuple params in CPU hotpath code (#2502) --- .../scala/caliban/execution/Executor.scala | 36 ++++++++++--------- .../caliban/interop/jsoniter/jsoniter.scala | 12 +++---- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/core/src/main/scala/caliban/execution/Executor.scala b/core/src/main/scala/caliban/execution/Executor.scala index a6fc278ba3..2051b8b2d7 100644 --- a/core/src/main/scala/caliban/execution/Executor.scala +++ b/core/src/main/scala/caliban/execution/Executor.scala @@ -189,8 +189,8 @@ object Executor { (aliasedName, field, fieldInfo(f, aliasedName, path, f.directives)) } - val filteredFields = mergeFields(currentField, objectName) - val (deferred, eager) = + val filteredFields = mergeFields(currentField, objectName) + val t = if (Feature.isDeferEnabled(flags)) { filteredFields.partitionMap { f => val entry = reduceField(f) @@ -203,14 +203,14 @@ object Executor { } } else (Nil, filteredFields.map(reduceField)) - val eagerReduced = reduceObject(eager) - deferred match { + val eagerReduced = reduceObject(t._2) + t._1 match { case Nil => eagerReduced case d => DeferStep( eagerReduced, d.groupBy(_._1).toList.map { case (label, labelAndFields) => - val (_, fields) = labelAndFields.unzip + val fields = labelAndFields.map(_._2) reduceObject(fields) -> label }, path @@ -419,10 +419,7 @@ object Executor { } if (hasQueries || wrapPureValues) ReducedStep.ObjectStep(items, hasPures, !hasQueries) - else - PureStep( - ObjectValue(items.asInstanceOf[List[(String, PureStep, FieldInfo)]].map { case (k, v, _) => (k, v.value) }) - ) + else PureStep(ObjectValue(items.asInstanceOf[List[(String, PureStep, FieldInfo)]].map(t => (t._1, t._2.value)))) } } @@ -506,7 +503,7 @@ object Executor { var resps = results var names = steps while (resps ne nil) { - val (name, _, _) = names.head + val name = names.head._1 builder addOne ((name, resps.head)) resps = resps.tail names = names.tail @@ -515,11 +512,16 @@ object Executor { } steps match { - case (name, step, info) :: Nil => + case t :: Nil => + val name = t._1 + val step = t._2 + val info = t._3 // Shortcut for single field queries objectFieldQuery(step, info, wrapPureValues && step.isPure).map(v => ObjectValue((name, v) :: Nil)) - case steps => - collectAll(steps, isTopLevelField) { case (_, step, info) => + case steps => + collectAll(steps, isTopLevelField) { t => + val step = t._2 + val info = t._3 // Only way we could have ended with pure fields here is if we wrap pure values, so we check that first as it's cheaper objectFieldQuery(step, info, wrapPureValues && step.isPure) }.map(combineQueryResults) @@ -555,8 +557,10 @@ object Executor { var resolved: List[ResponseValue] = nil var remaining = steps while (remaining ne nil) { - val t @ (name, step, _) = remaining.head - val value = step match { + val t = remaining.head + val name = t._1 + val step = t._2 + val value = step match { case PureStep(value) => value case _ => queries = t :: queries @@ -566,7 +570,7 @@ object Executor { names = name :: names remaining = remaining.tail } - collectAll(queries, isTopLevelField) { case (_, s, i) => objectFieldQuery(s, i) } + collectAll(queries, isTopLevelField)(t => objectFieldQuery(t._2, t._3)) .map(combineResults(names, resolved)) } diff --git a/core/src/main/scala/caliban/interop/jsoniter/jsoniter.scala b/core/src/main/scala/caliban/interop/jsoniter/jsoniter.scala index cea3d7e04d..ebcb852eb8 100644 --- a/core/src/main/scala/caliban/interop/jsoniter/jsoniter.scala +++ b/core/src/main/scala/caliban/interop/jsoniter/jsoniter.scala @@ -59,9 +59,9 @@ private[caliban] object ValueJsoniter { out.writeObjectStart() val iter = m.iterator while (iter.hasNext) { - val (k, v) = iter.next() - out.writeNonEscapedAsciiKey(k) - encodeInputValue(v, out) + val kv = iter.next() + out.writeNonEscapedAsciiKey(kv._1) + encodeInputValue(kv._2, out) } out.writeObjectEnd() } @@ -108,10 +108,10 @@ private[caliban] object ValueJsoniter { out.writeObjectStart() var remaining = l while (remaining ne Nil) { - val (k, v) = remaining.head + val kv = remaining.head remaining = remaining.tail - out.writeNonEscapedAsciiKey(k) - encodeResponseValue(v, out) + out.writeNonEscapedAsciiKey(kv._1) + encodeResponseValue(kv._2, out) } out.writeObjectEnd() }