asoft
sea

~ tiny vessels of code slowly floating out to sea

Powered by a motorboat called the S.S.Tumblr

1 year ago

@1:07am

Comments

an old man and a park bench

I sat down next to an old man on a park bench today. He said to me:

Are you just going to sit there?

So I said:

Why do you ask?

To which he replied:

I’m an old man. These days, what I enjoy most is to sit here and watch others go about their business, over and over, and over again.

I went on my way. I came back to the bench the next day and the old man and the bench was gone.

So I build myself a new bench to sit and watch on my own, occasionally glancing at my watch.

To Build a Bench

I bought a hammer and a few planks of wood and this is what I made:

package park

trait Bench {
  object Timing {
    case class Time(cpu: Long, user: Long, system: Long, real: Long) {
      val tuple = (cpu, user, system, real)
      def - (t: Time) = Time(
        cpu - t.cpu, user - t.user, system - t.system, real - t.real
      )
      def + (t: Time) = Time(
        cpu + t.cpu, user + t.user, system + t.system, real + t.real
      )
    }
    def cpu = get(bean getCurrentThreadCpuTime)
    def user = get(bean getCurrentThreadUserTime)
    def real = System.nanoTime
    def system = cpu - user
    def now = Time(cpu, user, system, real)
    val empty = Time(0l, 0l, 0l, 0l)
    def get(fn: => Long) = if(bean isCurrentThreadCpuTimeSupported) fn else 0l
    private val bean = java.lang.management.ManagementFactory.getThreadMXBean
  }

  def watch(n: Int, o: Int) = { 
    headers
    for(i <- Stream.range(0, o)) collect(n)
  }

  def collect(times: Int) = tell(subject, (Timing.empty /: observe(times))(_+_))

  def subject = getClass getName

  def observe(n: Int) = for(i <- Stream.range(0, n)) yield time { run }

  def time(block: => Any) = {
    val before = Timing.now
    block
    val after = Timing.now
    after - before
  }

  def headers = println(
     (" "*subject.size)+"\t\tcpu\t\tuser\t\tsystem\t\treal"
   )

  def tell(subject: String, time: Timing.Time) = {
    def sec(n: Long) = n / 1000000000.0
    val (cpu, user, system, real) = time.tuple
    println(
      "%s\t\t%f\t%f\t%f\t%f" format(
        subject, sec(cpu), sec(user), sec(system), sec(real)
       )
    )
  }

  /** where unicorns do run wild */
  def run
}

Bird Watching and other Leisurely Observations

I stepped back to have a look at this new park bench.

From here, I can watch flocks of inline invokations fly by, one or more times.

scala> val b = new Bench { def run = 1+1; override def subject = "plus" }
scala> b watch(2, 2)

I jotted down what I saw.

            cpu             user        system     real
plus        0.000067        0.000027    0.000021   0.000046
plus        0.000054        0.000028    0.000021   0.000108

Under a tree, I can watch those pass the time by reading favored books.

object BookShelfBench extends BookShelf with park.Bench {
  def run = read(Book("a tale of two cities"))
  override def subject = "reading"
}

BookShelfBench watch(10, 1)

To be honest, I really didn’t have time to watch them finish this book.

              cpu      user     system   real
reading        a       really   long     time...

This was just a quick and silly re-composition of an idea I had while glancing at scala.testing.Benchmark. This idea may become a real project as some point on the githubs. For now it was just flash coding. Isn’t composition fun?

blog comments powered by Disqus