| author | desharna | 
| Sat, 04 Jun 2022 16:00:14 +0200 | |
| changeset 75504 | 75e1b94396c6 | 
| parent 75393 | 87ebf5a50283 | 
| child 76592 | ec8bf1268f45 | 
| 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 | |
| 65920 | 16 | def timeit[A]( | 
| 17 | message: String = "", | |
| 18 | enabled: Boolean = true, | |
| 75393 | 19 | output: String => Unit = Output.warning(_) | 
| 20 |   )(e: => A): A = {
 | |
| 47653 | 21 |     if (enabled) {
 | 
| 56691 | 22 | val start = Time.now() | 
| 47653 | 23 | val result = Exn.capture(e) | 
| 56691 | 24 | val stop = Time.now() | 
| 46768 | 25 | |
| 56691 | 26 | val timing = stop - start | 
| 65920 | 27 |       if (timing.is_relevant) {
 | 
| 28 | output( | |
| 29 | (if (message == null || message == "") "" else message + ": ") + | |
| 47653 | 30 | timing.message + " elapsed time") | 
| 65920 | 31 | } | 
| 46768 | 32 | |
| 47653 | 33 | Exn.release(result) | 
| 34 | } | |
| 35 | else e | |
| 65920 | 36 | } | 
| 72015 | 37 | |
| 38 | def factor_format(f: Double): String = | |
| 39 | String.format(Locale.ROOT, ", factor %.2f", java.lang.Double.valueOf(f)) | |
| 45664 | 40 | } | 
| 41 | ||
| 75393 | 42 | sealed case class Timing(elapsed: Time, cpu: Time, gc: Time) {
 | 
| 64089 | 43 | def is_zero: Boolean = elapsed.is_zero && cpu.is_zero && gc.is_zero | 
| 46768 | 44 | def is_relevant: Boolean = elapsed.is_relevant || cpu.is_relevant || gc.is_relevant | 
| 45 | ||
| 64084 | 46 | def resources: Time = cpu + gc | 
| 47 | ||
| 75393 | 48 |   def factor: Option[Double] = {
 | 
| 64084 | 49 | val t1 = elapsed.seconds | 
| 50 | val t2 = resources.seconds | |
| 51 | if (t1 >= 3.0 && t2 >= 3.0) Some(t2 / t1) else None | |
| 52 | } | |
| 53 | ||
| 51587 | 54 | def + (t: Timing): Timing = Timing(elapsed + t.elapsed, cpu + t.cpu, gc + t.gc) | 
| 55 | ||
| 62587 
e31bf8ed5397
clarified messages, notably on Windows where CPU time of poly.exe is not measured;
 wenzelm parents: 
62571diff
changeset | 56 | def message: String = | 
| 
e31bf8ed5397
clarified messages, notably on Windows where CPU time of poly.exe is not measured;
 wenzelm parents: 
62571diff
changeset | 57 | 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 | 58 | |
| 72015 | 59 | def message_factor: String = | 
| 60 | elapsed.message + " elapsed time, " + cpu.message + " cpu time, " + gc.message + " GC time" + | |
| 61 | Timing.factor_format(cpu.seconds / elapsed.seconds) | |
| 62 | ||
| 75393 | 63 |   def message_resources: String = {
 | 
| 64084 | 64 | val factor_text = | 
| 65 |       factor match {
 | |
| 72015 | 66 | case Some(f) => Timing.factor_format(f) | 
| 64084 | 67 | case None => "" | 
| 68 | } | |
| 69 | if (resources.seconds >= 3.0) | |
| 70 | elapsed.message_hms + " elapsed time, " + resources.message_hms + " cpu time" + factor_text | |
| 62587 
e31bf8ed5397
clarified messages, notably on Windows where CPU time of poly.exe is not measured;
 wenzelm parents: 
62571diff
changeset | 71 | else | 
| 64084 | 72 | elapsed.message_hms + " elapsed time" + factor_text | 
| 62571 | 73 | } | 
| 74 | ||
| 57912 | 75 | override def toString: String = message | 
| 67858 | 76 | |
| 77 | def json: JSON.Object.T = | |
| 78 |     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 | 79 | } |