| author | wenzelm | 
| Sat, 02 Dec 2023 19:57:57 +0100 | |
| changeset 79114 | 686b7b14d041 | 
| parent 77368 | 7c57d9586f4c | 
| child 83172 | e69ebc4782a3 | 
| permissions | -rw-r--r-- | 
| 40393 | 1 | /* Title: Pure/General/timing.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 65920 | 4 | Support for time measurement. | 
| 40393 | 5 | */ | 
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 45664 | 9 | |
| 62571 | 10 | import java.util.Locale | 
| 11 | ||
| 12 | ||
| 75393 | 13 | object Timing {
 | 
| 65920 | 14 | val zero: Timing = Timing(Time.zero, Time.zero, Time.zero) | 
| 51587 | 15 | |
| 76593 
badb5264f7b9
clarified signature: just one level of arguments to avoid type-inference problems;
 wenzelm parents: 
76592diff
changeset | 16 | def timeit[A](body: => A, | 
| 76592 | 17 | message: Exn.Result[A] => String = null, | 
| 65920 | 18 | enabled: Boolean = true, | 
| 75393 | 19 | output: String => Unit = Output.warning(_) | 
| 76593 
badb5264f7b9
clarified signature: just one level of arguments to avoid type-inference problems;
 wenzelm parents: 
76592diff
changeset | 20 |   ): A = {
 | 
| 47653 | 21 |     if (enabled) {
 | 
| 56691 | 22 | val start = Time.now() | 
| 76593 
badb5264f7b9
clarified signature: just one level of arguments to avoid type-inference problems;
 wenzelm parents: 
76592diff
changeset | 23 | val result = Exn.capture(body) | 
| 56691 | 24 | val stop = Time.now() | 
| 46768 | 25 | |
| 56691 | 26 | val timing = stop - start | 
| 65920 | 27 |       if (timing.is_relevant) {
 | 
| 76592 | 28 | val msg = if (message == null) null else message(result) | 
| 77368 | 29 | output(if_proper(msg, msg + ": ") + timing.message + " elapsed time") | 
| 65920 | 30 | } | 
| 46768 | 31 | |
| 47653 | 32 | Exn.release(result) | 
| 33 | } | |
| 76593 
badb5264f7b9
clarified signature: just one level of arguments to avoid type-inference problems;
 wenzelm parents: 
76592diff
changeset | 34 | else body | 
| 65920 | 35 | } | 
| 72015 | 36 | |
| 37 | def factor_format(f: Double): String = | |
| 38 | String.format(Locale.ROOT, ", factor %.2f", java.lang.Double.valueOf(f)) | |
| 45664 | 39 | } | 
| 40 | ||
| 75393 | 41 | sealed case class Timing(elapsed: Time, cpu: Time, gc: Time) {
 | 
| 64089 | 42 | def is_zero: Boolean = elapsed.is_zero && cpu.is_zero && gc.is_zero | 
| 46768 | 43 | def is_relevant: Boolean = elapsed.is_relevant || cpu.is_relevant || gc.is_relevant | 
| 44 | ||
| 64084 | 45 | def resources: Time = cpu + gc | 
| 46 | ||
| 75393 | 47 |   def factor: Option[Double] = {
 | 
| 64084 | 48 | val t1 = elapsed.seconds | 
| 49 | val t2 = resources.seconds | |
| 50 | if (t1 >= 3.0 && t2 >= 3.0) Some(t2 / t1) else None | |
| 51 | } | |
| 52 | ||
| 51587 | 53 | def + (t: Timing): Timing = Timing(elapsed + t.elapsed, cpu + t.cpu, gc + t.gc) | 
| 54 | ||
| 62587 
e31bf8ed5397
clarified messages, notably on Windows where CPU time of poly.exe is not measured;
 wenzelm parents: 
62571diff
changeset | 55 | def message: String = | 
| 
e31bf8ed5397
clarified messages, notably on Windows where CPU time of poly.exe is not measured;
 wenzelm parents: 
62571diff
changeset | 56 | elapsed.message + " elapsed time, " + cpu.message + " cpu time, " + gc.message + " GC time" | 
| 
e31bf8ed5397
clarified messages, notably on Windows where CPU time of poly.exe is not measured;
 wenzelm parents: 
62571diff
changeset | 57 | |
| 72015 | 58 | def message_factor: String = | 
| 59 | elapsed.message + " elapsed time, " + cpu.message + " cpu time, " + gc.message + " GC time" + | |
| 60 | Timing.factor_format(cpu.seconds / elapsed.seconds) | |
| 61 | ||
| 75393 | 62 |   def message_resources: String = {
 | 
| 64084 | 63 | val factor_text = | 
| 64 |       factor match {
 | |
| 72015 | 65 | case Some(f) => Timing.factor_format(f) | 
| 64084 | 66 | case None => "" | 
| 67 | } | |
| 76595 | 68 |     if (resources.seconds >= 3.0) {
 | 
| 64084 | 69 | elapsed.message_hms + " elapsed time, " + resources.message_hms + " cpu time" + factor_text | 
| 76595 | 70 | } | 
| 71 |     else {
 | |
| 64084 | 72 | elapsed.message_hms + " elapsed time" + factor_text | 
| 76595 | 73 | } | 
| 62571 | 74 | } | 
| 75 | ||
| 57912 | 76 | override def toString: String = message | 
| 67858 | 77 | |
| 78 | def json: JSON.Object.T = | |
| 79 |     JSON.Object("elapsed" -> elapsed.seconds, "cpu" -> cpu.seconds, "gc" -> gc.seconds)
 | |
| 40848 
8662b9b1f123
more abstract/uniform handling of time, preferring seconds as Double;
 wenzelm parents: 
40393diff
changeset | 80 | } |