fs2 icon indicating copy to clipboard operation
fs2 copied to clipboard

Channel - SendAll: work chunk-wise

Open diesalbla opened this issue 3 years ago • 4 comments

Write sendAll to work at level of chunks, to avoid some overheads of Stream evalMap (since there is no downstream cut).

diesalbla avatar Apr 16 '22 12:04 diesalbla

Have we measured this to make a difference?

SystemFw avatar Apr 19 '22 13:04 SystemFw

Have we measured this to make a difference?

No. It is based on the knowledge and interpretation of the definition of evalMap:

  def evalMap[F2[x] >: F[x], O2](f: O => F2[O2]): Stream[F2, O2] =
    flatMap(o => Stream.eval(f(o)))

  def eval[F[_], O](fo: F[O]): Stream[F, O] =
    new Stream(Pull.eval(fo).flatMap(Pull.output1))

For each object in the source stream, the evalMap method would create 1. a Pull.Eval object, 2. a Bind object, 3. a Pull.Output object, and 4. a Chunk object, which contains 5. a boxed Boolean object (edit although it may be that the JVM already caches this Boolean). Making the code work on chunks would reduce that from once per element to once per chunk.

The idea was to replace the main code with a Pull, but it seemed that chunk-wise processing would be good enough.

def go(s: Stream[F, O]): Pull[F, INothing, Unit] = 
  s.pull.uncons.flatMap {
    case None => Pull.eval(close.void)
    case Some((h, t)) => 
      Pull.eval(sendChunk(h)).flatMap {
        case true => go(t)
        case false => Pull.eval(close.void)
      }
  }

diesalbla avatar Apr 19 '22 23:04 diesalbla

Personally I'm a bit skeptical of reasoning about performance this way, we've had several cases where code that ought to be slower ended up being faster, including in Channel itself with the use of List. This type of change makes the code less readable, so imho it should be justified by a benchmark if the sole reason for having it is performance.

SystemFw avatar Apr 20 '22 06:04 SystemFw

Agreed, we'll need benchmarks of some form for this - at very least informal ones if not full JMH ones.

mpilquist avatar Apr 21 '22 12:04 mpilquist

Since the overhead of evalMap is a bit smaller now, this may not be needed.

diesalbla avatar Oct 16 '22 18:10 diesalbla