| author | wenzelm | 
| Fri, 12 Jul 2013 21:13:57 +0200 | |
| changeset 52630 | fe411c1dc180 | 
| parent 51615 | 072a7249e1ac | 
| child 52888 | 671421cef590 | 
| permissions | -rw-r--r-- | 
| 51240 | 1 | /* Title: Pure/Tools/ml_statistics.scala | 
| 50685 | 2 | Author: Makarius | 
| 3 | ||
| 4 | ML runtime statistics. | |
| 5 | */ | |
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 9 | ||
| 51432 | 10 | import scala.collection.mutable | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 11 | import scala.collection.immutable.{SortedSet, SortedMap}
 | 
| 50691 | 12 | import scala.swing.{Frame, Component}
 | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 13 | |
| 50689 | 14 | import org.jfree.data.xy.{XYSeries, XYSeriesCollection}
 | 
| 15 | import org.jfree.chart.{JFreeChart, ChartPanel, ChartFactory}
 | |
| 16 | import org.jfree.chart.plot.PlotOrientation | |
| 17 | ||
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 18 | |
| 50685 | 19 | object ML_Statistics | 
| 20 | {
 | |
| 50690 | 21 | /* content interpretation */ | 
| 22 | ||
| 23 | final case class Entry(time: Double, data: Map[String, Double]) | |
| 24 | ||
| 50982 | 25 | def apply(name: String, stats: List[Properties.T]): ML_Statistics = | 
| 26 | new ML_Statistics(name, stats) | |
| 50690 | 27 | |
| 50982 | 28 | def apply(info: Build.Log_Info): ML_Statistics = | 
| 29 | apply(info.name, info.stats) | |
| 30 | ||
| 31 |   val empty = apply("", Nil)
 | |
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 32 | |
| 50690 | 33 | |
| 34 | /* standard fields */ | |
| 35 | ||
| 36 |   val GC_fields = ("GCs", List("partial_GCs", "full_GCs"))
 | |
| 37 | ||
| 38 | val heap_fields = | |
| 39 |     ("Heap", List("size_heap", "size_allocation", "size_allocation_free",
 | |
| 40 | "size_heap_free_last_full_GC", "size_heap_free_last_GC")) | |
| 41 | ||
| 42 | val threads_fields = | |
| 43 |     ("Threads", List("threads_total", "threads_in_ML", "threads_wait_condvar",
 | |
| 44 | "threads_wait_IO", "threads_wait_mutex", "threads_wait_signal")) | |
| 45 | ||
| 51432 | 46 |   val time_fields = ("Time", List("time_CPU", "time_GC"))
 | 
| 47 | ||
| 48 |   val speed_fields = ("Speed", List("speed_CPU", "speed_GC"))
 | |
| 50690 | 49 | |
| 50 | val tasks_fields = | |
| 50974 
55f8bd61b029
added "tasks_proof" statistics, via slighly odd global reference Future.forked_proofs (NB: Future.report_status is intertwined with scheduler thread);
 wenzelm parents: 
50855diff
changeset | 51 |     ("Future tasks",
 | 
| 
55f8bd61b029
added "tasks_proof" statistics, via slighly odd global reference Future.forked_proofs (NB: Future.report_status is intertwined with scheduler thread);
 wenzelm parents: 
50855diff
changeset | 52 |       List("tasks_proof", "tasks_ready", "tasks_pending", "tasks_running", "tasks_passive"))
 | 
| 50690 | 53 | |
| 54 | val workers_fields = | |
| 55 |     ("Worker threads", List("workers_total", "workers_active", "workers_waiting"))
 | |
| 56 | ||
| 57 | val standard_fields = | |
| 51432 | 58 | List(GC_fields, heap_fields, threads_fields, time_fields, speed_fields, | 
| 59 | tasks_fields, workers_fields) | |
| 50685 | 60 | } | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 61 | |
| 50982 | 62 | final class ML_Statistics private(val name: String, val stats: List[Properties.T]) | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 63 | {
 | 
| 50690 | 64 |   val Now = new Properties.Double("now")
 | 
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 65 | def now(props: Properties.T): Double = Now.unapply(props).get | 
| 50690 | 66 | |
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 67 | require(stats.forall(props => Now.unapply(props).isDefined)) | 
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 68 | |
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 69 | val time_start = if (stats.isEmpty) 0.0 else now(stats.head) | 
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 70 | val duration = if (stats.isEmpty) 0.0 else now(stats.last) - time_start | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 71 | |
| 50689 | 72 | val fields: Set[String] = | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 73 | SortedSet.empty[String] ++ | 
| 50690 | 74 | (for (props <- stats.iterator; (x, _) <- props.iterator if x != Now.name) | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 75 | yield x) | 
| 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 76 | |
| 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 77 | val content: List[ML_Statistics.Entry] = | 
| 51432 | 78 |   {
 | 
| 79 | var last_edge = Map.empty[String, (Double, Double, Double)] | |
| 80 | val result = new mutable.ListBuffer[ML_Statistics.Entry] | |
| 81 |     for (props <- stats) {
 | |
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 82 | val time = now(props) - time_start | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 83 | require(time >= 0.0) | 
| 51432 | 84 | |
| 85 | // rising edges -- relative speed | |
| 86 | val speeds = | |
| 87 |         for ((key, value) <- props; a <- Library.try_unprefix("time", key)) yield {
 | |
| 88 | val (x0, y0, s0) = last_edge.get(a) getOrElse (0.0, 0.0, 0.0) | |
| 89 | ||
| 90 | val x1 = time | |
| 91 | val y1 = java.lang.Double.parseDouble(value) | |
| 92 | val s1 = if (x1 == x0) 0.0 else (y1 - y0) / (x1 - x0) | |
| 93 | ||
| 94 |           val b = ("speed" + a).intern
 | |
| 95 |           if (y1 > y0) { last_edge += (a -> (x1, y1, s1)); (b, s1) } else (b, s0)
 | |
| 96 | } | |
| 97 | ||
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 98 | val data = | 
| 51432 | 99 | SortedMap.empty[String, Double] ++ speeds ++ | 
| 50690 | 100 | (for ((x, y) <- props.iterator if x != Now.name) | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 101 | yield (x, java.lang.Double.parseDouble(y))) | 
| 51432 | 102 | result += ML_Statistics.Entry(time, data) | 
| 103 | } | |
| 104 | result.toList | |
| 105 | } | |
| 50689 | 106 | |
| 107 | ||
| 108 | /* charts */ | |
| 109 | ||
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 110 | def update_data(data: XYSeriesCollection, selected_fields: Iterable[String]) | 
| 50689 | 111 |   {
 | 
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 112 | data.removeAllSeries | 
| 50689 | 113 |     for {
 | 
| 50690 | 114 | field <- selected_fields.iterator | 
| 50689 | 115 | series = new XYSeries(field) | 
| 116 |     } {
 | |
| 117 | content.foreach(entry => series.add(entry.time, entry.data(field))) | |
| 118 | data.addSeries(series) | |
| 119 | } | |
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 120 | } | 
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 121 | |
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 122 | def chart(title: String, selected_fields: Iterable[String]): JFreeChart = | 
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 123 |   {
 | 
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 124 | val data = new XYSeriesCollection | 
| 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 125 | update_data(data, selected_fields) | 
| 50689 | 126 | |
| 127 | ChartFactory.createXYLineChart(title, "time", "value", data, | |
| 128 | PlotOrientation.VERTICAL, true, true, true) | |
| 129 | } | |
| 130 | ||
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 131 | def chart(arg: (String, Iterable[String])): JFreeChart = chart(arg._1, arg._2) | 
| 50691 | 132 | |
| 50981 | 133 | def show_standard_frames(): Unit = | 
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 134 | ML_Statistics.standard_fields.map(chart(_)).foreach(c => | 
| 50691 | 135 |       Swing_Thread.later {
 | 
| 50854 | 136 |         new Frame {
 | 
| 51615 
072a7249e1ac
separate module "GUI", to keep this out of the way of generic Isabelle_System operations, notably for non-Isabelle/jEdit applications;
 wenzelm parents: 
51432diff
changeset | 137 | iconImage = GUI.isabelle_image() | 
| 50982 | 138 | title = name | 
| 50854 | 139 | contents = Component.wrap(new ChartPanel(c)) | 
| 140 | visible = true | |
| 141 | } | |
| 50697 
82e9178e6a98
improved Monitor_Dockable, based on ML_Statistics operations;
 wenzelm parents: 
50691diff
changeset | 142 | }) | 
| 50688 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 143 | } | 
| 
f02864682307
some support for ML statistics content interpretation;
 wenzelm parents: 
50685diff
changeset | 144 |