table ← {opts←⍬} ##.cmpx exprs ⍝ Approx expression timings. "By what course of calculation can these results be arrived at by the machine in the shortest time?" - Passages from the Life of a Philosopher, Charles Babbage, 1864. [exprs] is a vector of character vectors, each representing a result-returning expression. Each expression is compiled into a loop, and its evaluation timed for 1, 2, 4, 8, 16, ··· iterations. The iteration count is doubled until the mean time to execute is more than [secs]. Finally, an empty loop is compiled and its execution time for the final number of iterations subtracted to give nett execution time in seconds for each expression. Optional left argument [opts] specifies a vector of 0-4 items. Defaults are as- sumed if fewer than 4 items are supplied. The options are: raw: 0:graphical display as below (default); 1:raw numeric vector of seconds. cpu: 0:elapsed ⎕AI[3] time (default); 1:cpu ⎕AI[2] time. cols: Maximum column-width for histogram. 0 implies the default width of 40. secs: Test period in seconds (default 1). By default, [cmpx] returns a character matrix representing a 5-column table: cmpx'⎕io⊃⎕a' '⎕a[⎕io]' '⍬⍴⎕a' '1↑⎕a' ⍝ CoMPare eXpressions. ⎕io⊃⎕a → 1.1E¯6 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ ⎕a[⎕io] → 1.7E¯6 | +51% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ ⍬⍴⎕a → 1.0E¯6 | -8% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ * 1↑⎕a → 1.3E¯6 | +16% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ │ │ │ │ │ │ │ │ │ └─ Histogram for at-a-glance comparison. │ │ │ └───── Percentage difference relative to first expression. │ │ └─────────────── Approx time in seconds for a single iteration. │ └───────────────────────── Subject expression. └─────────────────────────── Warning for results not identical to the first one. (The first three expressions return a scalar result and the fourth, a 1-item vector). Given a _single_ expression, [cmpx] returns only the number of seconds taken to execute it: cmpx'⎕io⊃⎕a' ⍝ Time single expression. 1.3E¯6 NB: expressions must not contain diamonds: cmpx't+t←2+3' ⍝ this will work but cmpx't←2+3 ⋄ t+t' ⍝ this will hang :-( Technical notes: Notice in the coding of this function, that name conflicts are avoided by having the subject expression timings execute lexically _outside_ the main operator. Further, the small amount of code visible at execution (⍎) time has been care- fully chosen to be both ⎕IO and ⎕ML independent: cmpx←{ ··· 1{ (⍎⍵)-⎕AI ⍝ Execute expression outside }{⎕IO ⎕ML←0 ⍝ main operator so that no system variable times←⍺ ⍺⍺{ ⍝ or name conflicts occur. Differences in the expression results are detected by a final re-execution of each expression in the _right_ operand of the main operator, which is again out- side the main operator body and so ⎕IO and ⎕ML independent. ··· diff←{⍵⊃' *'}¨×{⍵⍳⍵},⍵⍵¨⍵ ⍝ result differences. ··· }{ ⍝ right operand: ⍎⍵ ⍝ execute expr in its native envt. }⍵ ⍝ vector of subject expressions. Examples: cmpx'100⍴2' '100/2' ⍝ / is slower (though easier to spell. 100⍴2 → 9.5E¯7 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ 100/2 → 2.6E¯6 | +175% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ cmpx'⊃ ⊂⍬' '↑ ⊂⍬' ⍝ first quicker than mix for disclose. ⊃ ⊂⍬ → 4.2E¯7 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ ↑ ⊂⍬ → 1.1E¯6 | +153% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ ⍝ Stranding (⍬ ⍬ ... ⍬) appears to be an O(n*2) operation: cmpx 11/'⍬' ⍝ 10 strandings. 6.4E¯6 cmpx 101/'⍬' ⍝ 100 strandings. 1.9E¯4 cmpx 1001/'⍬' ⍝ 1000 strandings. 1.5E¯2 cmpx 10001/'⍬' ⍝ 10000 strandings 1.5E0 1 cmpx'⎕io⊃⎕a' '⎕a[⎕io]' '⍬⍴⎕a' '1↑⎕a' ⍝ option: raw exprssion times. 4.472732544E¯7 5.502700806E¯7 4.024505615E¯7 5.06401062E¯7 (1 0)(1 1) cmpx¨ ⊂'osc¨⍳1e3' ⍝ elapsed vs cpu ⎕AI times. 0.0673125 0.06725 See also: time profile cf Back to: contents Back to: Workspaces