All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kyo.bench.PingPongBench.scala Maven / Gradle / Ivy

There is a newer version: 3.0.7
Show newest version
package kyo.bench

import org.openjdk.jmh.annotations._
import cats.effect.IO
import kyo._
import kyo.ios._
import zio.{ZIO, UIO}
import java.util.concurrent.Executors
import kyo.concurrent.fibers._
import kyo.concurrent.channels._
import kyo.concurrent.Access

import kyo.bench.Bench
import java.util.concurrent.atomic.AtomicInteger
import cats.effect.kernel.Deferred
import kyo.concurrent.atomics._

class PingPongBench extends Bench.ForkOnly[Unit] {

  val depth = 1000

  def catsBench(): IO[Unit] = {
    import cats.effect.std.Queue

    def repeat[A](n: Int)(io: IO[A]): IO[A] =
      if (n <= 1) io
      else io.flatMap(_ => repeat(n - 1)(io))

    def iterate(deferred: Deferred[IO, Unit], n: Int): IO[Any] =
      for {
        ref   <- IO.ref(n)
        queue <- Queue.bounded[IO, Unit](1)
        effect = queue.offer(()).start >>
          queue.take >>
          ref
            .modify(n =>
              (n - 1, if (n == 1) deferred.complete(()) else IO.unit)
            )
            .flatten
        _ <- repeat(depth)(effect.start)
      } yield ()

    for {
      deferred <- IO.deferred[Unit]
      _        <- iterate(deferred, depth).start
      _        <- deferred.get
    } yield ()
  }

  def kyoBench() = Fibers.runBlocking(Fibers.fork(kyoBenchFiber()))

  override def kyoBenchFiber(): Unit > (IOs with Fibers) = {
    import kyo.concurrent.queues._

    def repeat[A](n: Int)(io: A > (IOs with Fibers)): A > (IOs with Fibers) =
      if (n <= 1) io
      else io.flatMap(_ => repeat(n - 1)(io))

    def iterate(promise: Promise[Unit], n: Int): Unit > (IOs with Fibers) =
      for {
        ref  <- Atomics.initInt(n)
        chan <- Channels.init[Unit](1)
        effect =
          for {
            _ <- Fibers.forkFiber(chan.put(()))
            _ <- chan.take
            n <- ref.decrementAndGet
            _ <- if (n == 0) promise.complete(()).unit else IOs.unit
          } yield ()
        _ <- repeat(depth)(Fibers.forkFiber(effect))
      } yield ()

    for {
      promise <- Fibers.initPromise[Unit]
      _       <- Fibers.forkFiber(iterate(promise, depth))
      _       <- promise.get
    } yield ()
  }

  def zioBench(): UIO[Unit] = {
    import zio.Queue
    import zio.Promise
    import zio.Ref

    def repeat[R, E, A](n: Int)(zio: ZIO[R, E, A]): ZIO[R, E, A] =
      if (n <= 1) zio
      else zio *> repeat(n - 1)(zio)

    def iterate(promise: Promise[Nothing, Unit], n: Int): ZIO[Any, Nothing, Any] =
      for {
        ref   <- Ref.make(n)
        queue <- Queue.bounded[Unit](1)
        effect = queue.offer(()).forkDaemon *>
          queue.take *>
          ref
            .modify(n =>
              (if (n == 1) promise.succeed(()) else ZIO.unit, n - 1)
            )
            .flatten
        _ <- repeat(depth)(effect.forkDaemon)
      } yield ()

    for {
      promise <- Promise.make[Nothing, Unit]
      _       <- iterate(promise, depth).forkDaemon
      _       <- promise.await
    } yield ()
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy