Skip to content

Commit 77a694d

Browse files
authored
improve performance of parallel operations (#90)
1 parent 29c6192 commit 77a694d

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

zio-query/shared/src/main/scala/zio/query/ZQuery.scala

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -442,10 +442,17 @@ object ZQuery {
442442
def foreach[R, E, A, B, Collection[+Element] <: Iterable[Element]](
443443
as: Collection[A]
444444
)(f: A => ZQuery[R, E, B])(implicit bf: BuildFrom[Collection[A], B, Collection[B]]): ZQuery[R, E, Collection[B]] =
445-
as.foldLeft[ZQuery[R, E, Builder[B, Collection[B]]]](ZQuery.succeed(bf.newBuilder(as)))((bs, a) =>
446-
bs.zipWith(f(a))(_ += _)
447-
)
448-
.map(_.result())
445+
if (as.isEmpty) ZQuery.succeed(bf.newBuilder(as).result)
446+
else {
447+
val iterator = as.iterator
448+
var builder: ZQuery[R, E, Builder[B, Collection[B]]] = null
449+
while (iterator.hasNext) {
450+
val a = iterator.next()
451+
if (builder eq null) builder = f(a).map(bf.newBuilder(as) += _)
452+
else builder = builder.zipWith(f(a))(_ += _)
453+
}
454+
builder.map(_.result())
455+
}
449456

450457
/**
451458
* Performs a query for each element in a collection, collecting the results
@@ -455,10 +462,17 @@ object ZQuery {
455462
def foreachPar[R, E, A, B, Collection[+Element] <: Iterable[Element]](
456463
as: Collection[A]
457464
)(f: A => ZQuery[R, E, B])(implicit bf: BuildFrom[Collection[A], B, Collection[B]]): ZQuery[R, E, Collection[B]] =
458-
as.foldLeft[ZQuery[R, E, Builder[B, Collection[B]]]](ZQuery.succeed(bf.newBuilder(as)))((bs, a) =>
459-
bs.zipWithPar(f(a))(_ += _)
460-
)
461-
.map(_.result())
465+
if (as.isEmpty) ZQuery.succeed(bf.newBuilder(as).result)
466+
else {
467+
val iterator = as.iterator
468+
var builder: ZQuery[R, E, Builder[B, Collection[B]]] = null
469+
while (iterator.hasNext) {
470+
val a = iterator.next()
471+
if (builder eq null) builder = f(a).map(bf.newBuilder(as) += _)
472+
else builder = builder.zipWithPar(f(a))(_ += _)
473+
}
474+
builder.map(_.result())
475+
}
462476

463477
/**
464478
* Constructs a query from an effect.

zio-query/shared/src/main/scala/zio/query/internal/Continue.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ private[query] sealed trait Continue[-R, +E, +A] { self =>
114114
final def zipWithPar[R1 <: R, E1 >: E, B, C](that: Continue[R1, E1, B])(f: (A, B) => C): Continue[R1, E1, C] =
115115
(self, that) match {
116116
case (Effect(l), Effect(r)) => effect(l.zipWithPar(r)(f))
117-
case (Effect(l), Get(r)) => effect(l.zipWithPar(ZQuery.fromEffect(r))(f))
118-
case (Get(l), Effect(r)) => effect(ZQuery.fromEffect(l).zipWithPar(r)(f))
119-
case (Get(l), Get(r)) => get(l.zipWithPar(r)(f))
117+
case (Effect(l), Get(r)) => effect(l.zipWith(ZQuery.fromEffect(r))(f))
118+
case (Get(l), Effect(r)) => effect(ZQuery.fromEffect(l).zipWith(r)(f))
119+
case (Get(l), Get(r)) => get(l.zipWith(r)(f))
120120
}
121121

122122
}

0 commit comments

Comments
 (0)