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