Scala: time methods and track average & variance

Using this simple statistics library [https://chrisbissell.wordpress.com/2011/05/23/a-simple-but-very-flexible-statistics-library-in-scala/], a timing function [[https://stackoverflow.com/questions/9160001/how-to-profile-methods-in-scala#9160068]] and Hazelcast, we can track the variability of code performance in Scala.

Hazelcast setup:

val cfg = new Config("concepts")
val hazelcastInstance = Hazelcast.newHazelcastInstance(cfg)
val timings = hazelcastInstance.getList("timings").asInstanceOf[ICollection[Map[String, Double]]]

Then, for timing functions:

  var timer = 1
 
  def time[R](name: String, block: => R): R = {
    val maxMemory1 = runtime.maxMemory()
    val allocatedMemory1 = runtime.totalMemory()
    val freeMemory1 = runtime.freeMemory()
    val totalFree1 = freeMemory1 + (maxMemory1 - allocatedMemory1)
 
    val t0 = System.nanoTime()
    val result = block
    val t1 = System.nanoTime()
 
    val maxMemory2 = runtime.maxMemory()
    val allocatedMemory2 = runtime.totalMemory()
    val freeMemory2 = runtime.freeMemory()
    val totalFree2 = freeMemory2 + (maxMemory2 - allocatedMemory2)
 
    timings.add(
      Map[String, Double](
        timer + ".1 " + name + ".time" -> ((t1 - t0) / 1000000000.0),
        timer + ".2 " + name + ".totalFree" -> ((totalFree1 - totalFree2) / 1024.0 / 1024),
        timer + ".3 " + name + ".totalFree" -> ((allocatedMemory2 - allocatedMemory1) / 1024.0 / 1024)
      )
    )
 
    timer = timer + 1
 
    result
  }

Then, right before you finish, you can compute metrics, and print them out:

    import scala.collection.JavaConverters._
 
    println(
      "*********\n" +
        "Averages:\n" +
 
        timings.asScala.flatMap(
          (map) => map.toList
        ).groupBy(
          _._1
        ).map(
          (kv) =>
            (kv._1, kv._2.map(_._2))
        ).map(
          (kv) => (
            kv._1,
            mean(kv._2),
            2 * stddev(kv._2)
            )
        ).map(
          (kv) => kv._1 + ": " + format.format(kv._2) + " ± " + format.format(kv._3)
        ).toList.sorted
          .mkString("\n") +
        "\n********\n"
    )
 
    hazelcastInstance.shutdown()

This is a really easy way to track performance

Interested in Scala? I send out weekly, personalized emails with articles and conference talks. Click here to see an example and subscribe.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *