src/Pure/ML/ml_statistics.scala
author wenzelm
Thu, 03 Jan 2013 13:54:45 +0100
changeset 50697 82e9178e6a98
parent 50691 20beafe66748
child 50777 20126dd9772c
permissions -rw-r--r--
improved Monitor_Dockable, based on ML_Statistics operations; tuned signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50685
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/ML/ml_statistics.ML
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     3
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     4
ML runtime statistics.
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     5
*/
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     6
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     7
package isabelle
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     8
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
     9
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    10
import scala.collection.immutable.{SortedSet, SortedMap}
50691
20beafe66748 added standard_frames convenience;
wenzelm
parents: 50690
diff changeset
    11
import scala.swing.{Frame, Component}
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    12
50689
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
    13
import org.jfree.data.xy.{XYSeries, XYSeriesCollection}
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
    14
import org.jfree.chart.{JFreeChart, ChartPanel, ChartFactory}
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
    15
import org.jfree.chart.plot.PlotOrientation
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
    16
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    17
50685
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    18
object ML_Statistics
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    19
{
50690
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    20
  /* content interpretation */
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    21
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    22
  final case class Entry(time: Double, data: Map[String, Double])
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    23
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    24
  def apply(stats: List[Properties.T]): ML_Statistics = new ML_Statistics(stats)
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    25
  def apply(log: Path): ML_Statistics = apply(read_log(log))
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    26
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
    27
  val empty = apply(Nil)
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
    28
50690
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    29
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    30
  /* standard fields */
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    31
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    32
  val GC_fields = ("GCs", List("partial_GCs", "full_GCs"))
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    33
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    34
  val heap_fields =
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    35
    ("Heap", List("size_heap", "size_allocation", "size_allocation_free",
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    36
      "size_heap_free_last_full_GC", "size_heap_free_last_GC"))
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    37
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    38
  val threads_fields =
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    39
    ("Threads", List("threads_total", "threads_in_ML", "threads_wait_condvar",
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    40
      "threads_wait_IO", "threads_wait_mutex", "threads_wait_signal"))
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    41
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    42
  val time_fields =
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    43
    ("Time", List("time_GC_system", "time_GC_user", "time_non_GC_system", "time_non_GC_user"))
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    44
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    45
  val tasks_fields =
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    46
    ("Future tasks", List("tasks_ready", "tasks_pending", "tasks_running", "tasks_passive"))
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    47
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    48
  val workers_fields =
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    49
    ("Worker threads", List("workers_total", "workers_active", "workers_waiting"))
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    50
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    51
  val standard_fields =
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    52
    List(GC_fields, heap_fields, threads_fields, time_fields, tasks_fields, workers_fields)
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    53
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    54
50685
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    55
  /* read properties from build log */
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    56
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    57
  private val line_prefix = "\fML_statistics = "
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    58
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    59
  private val syntax = Outer_Syntax.empty + "," + "(" + ")" + "[" + "]"
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    60
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    61
  private object Parser extends Parse.Parser
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    62
  {
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    63
    private def stat: Parser[(String, String)] =
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    64
      keyword("(") ~ string ~ keyword(",") ~ string ~ keyword(")") ^^
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    65
      { case _ ~ x ~ _ ~ y ~ _ => (x, y) }
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    66
    private def stats: Parser[Properties.T] =
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    67
      keyword("[") ~> repsep(stat, keyword(",")) <~ keyword("]")
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    68
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    69
    def parse_stats(s: String): Properties.T =
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    70
    {
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    71
      parse_all(stats, Token.reader(syntax.scan(s))) match {
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    72
        case Success(result, _) => result
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    73
        case bad => error(bad.toString)
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    74
      }
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    75
    }
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    76
  }
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    77
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    78
  def read_log(log: Path): List[Properties.T] =
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    79
    for {
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    80
      line <- split_lines(File.read_gzip(log))
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    81
      if line.startsWith(line_prefix)
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    82
      stats = line.substring(line_prefix.length)
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    83
    } yield Parser.parse_stats(stats)
293e8ec4dfc8 ML runtime statistics: read properties from build log;
wenzelm
parents:
diff changeset
    84
}
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    85
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    86
final class ML_Statistics private(val stats: List[Properties.T])
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    87
{
50690
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    88
  val Now = new Properties.Double("now")
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
    89
  def now(props: Properties.T): Double = Now.unapply(props).get
50690
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    90
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
    91
  require(stats.forall(props => Now.unapply(props).isDefined))
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
    92
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
    93
  val time_start = if (stats.isEmpty) 0.0 else now(stats.head)
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
    94
  val duration = if (stats.isEmpty) 0.0 else now(stats.last) - time_start
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    95
50689
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
    96
  val fields: Set[String] =
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    97
    SortedSet.empty[String] ++
50690
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
    98
      (for (props <- stats.iterator; (x, _) <- props.iterator if x != Now.name)
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
    99
        yield x)
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   100
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   101
  val content: List[ML_Statistics.Entry] =
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   102
    stats.map(props => {
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   103
      val time = now(props) - time_start
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   104
      require(time >= 0.0)
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   105
      val data =
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   106
        SortedMap.empty[String, Double] ++
50690
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
   107
          (for ((x, y) <- props.iterator if x != Now.name)
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   108
            yield (x, java.lang.Double.parseDouble(y)))
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   109
      ML_Statistics.Entry(time, data)
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   110
    })
50689
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   111
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   112
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   113
  /* charts */
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   114
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   115
  def update_data(data: XYSeriesCollection, selected_fields: Iterable[String])
50689
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   116
  {
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   117
    data.removeAllSeries
50689
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   118
    for {
50690
03c4d75e8e32 some grouping of standard fields;
wenzelm
parents: 50689
diff changeset
   119
      field <- selected_fields.iterator
50689
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   120
      series = new XYSeries(field)
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   121
    } {
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   122
      content.foreach(entry => series.add(entry.time, entry.data(field)))
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   123
      data.addSeries(series)
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   124
    }
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   125
  }
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   126
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   127
  def chart(title: String, selected_fields: Iterable[String]): JFreeChart =
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   128
  {
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   129
    val data = new XYSeriesCollection
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   130
    update_data(data, selected_fields)
50689
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   131
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   132
    ChartFactory.createXYLineChart(title, "time", "value", data,
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   133
      PlotOrientation.VERTICAL, true, true, true)
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   134
  }
0607d557d073 some support for chart drawing;
wenzelm
parents: 50688
diff changeset
   135
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   136
  def chart(arg: (String, Iterable[String])): JFreeChart = chart(arg._1, arg._2)
50691
20beafe66748 added standard_frames convenience;
wenzelm
parents: 50690
diff changeset
   137
20beafe66748 added standard_frames convenience;
wenzelm
parents: 50690
diff changeset
   138
  def standard_frames: Unit =
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   139
    ML_Statistics.standard_fields.map(chart(_)).foreach(c =>
50691
20beafe66748 added standard_frames convenience;
wenzelm
parents: 50690
diff changeset
   140
      Swing_Thread.later {
20beafe66748 added standard_frames convenience;
wenzelm
parents: 50690
diff changeset
   141
        new Frame { contents = Component.wrap(new ChartPanel(c)); visible = true }
50697
82e9178e6a98 improved Monitor_Dockable, based on ML_Statistics operations;
wenzelm
parents: 50691
diff changeset
   142
      })
50688
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   143
}
f02864682307 some support for ML statistics content interpretation;
wenzelm
parents: 50685
diff changeset
   144