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

com.sksamuel.scam.ScamDsl.scala Maven / Gradle / Ivy

package com.sksamuel.scam

import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Await, Future}

/** @author Stephen Samuel */
trait ScamDsl {

  def measure[T](thunk: => T): (T, MeasurementResult) = {
    val stopwatch = new Stopwatch
    stopwatch.start()
    val t = thunk
    stopwatch.stop()
    val elapsed = stopwatch.elapsed
    (t, MeasurementResult(elapsed))
  }

  def benchmark(iterations: Int)(thunk: => Any): BenchmarkResult = benchmark(0, iterations)(thunk)
  def benchmark(warmUps: Int, iterations: Int)(thunk: => Any): BenchmarkResult = {

    repeat(warmUps)(thunk)

    val stopwatch = new Stopwatch

    stopwatch.start()
    repeat(iterations)(thunk)
    stopwatch.stop()

    val elapsed = stopwatch.elapsed
    BenchmarkResult(warmUps, iterations, elapsed)
  }

  def benchmarkFutures(iterations: Int)
                      (thunk: => Future[Any])
                      (implicit executionContext: ExecutionContext): BenchmarkResult = {
    val stopwatch = new Stopwatch
    stopwatch.start()
    val futures = for ( k <- 1 to iterations ) yield thunk
    val future = Future.sequence(futures)
    Await.ready(future, Duration.Inf)
    val elapsed = stopwatch.elapsed
    BenchmarkResult(0, iterations, elapsed)
  }

  def repeat(n: Int)(thunk: => Any): Unit = {
    for ( k <- 1 to n ) {
      thunk
    }
  }
}

object Scam extends ScamDsl

case class MeasurementResult(duration: FiniteDuration) {
  override def toString: String = {
    val sb = new StringBuilder
    sb append s"Total executed time: ${duration.toMillis} millis\n"
    sb.mkString
  }
}

case class BenchmarkResult(warmups: Int, iterations: Int, duration: FiniteDuration) {
  override def toString: String = {
    val avg = if (iterations == 0) 0 else duration.toMillis / iterations
    val perSecond = {
      if (duration.toMillis == 0) 0
      else "%.2f" format iterations / duration.toMillis.toDouble * 1000
    }
    val sb = new StringBuilder
    sb append s"$warmups warmup runs\n"
    sb append s"$iterations benchmarked iterations\n"
    sb append s"Total executed time: ${duration.toMillis} millis\n"
    sb append s"Average time per iteration: $avg millis\n"
    sb append s"$perSecond iterations per second\n"
    sb.mkString
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy