table ← ##.cmpx exprs                       ⍝ Approx expression timings.

Exprs is a vector of character vectors, each representing a result-returning APL
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 one second. Finally, an empty loop is compiled
and  its  execution  time  for the final number of iterations subtracted to give
nett execution time for each expression.

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).

NB: The  format  of  cmpx  has changed from earlier versions to make it a little
easier to read.  Further, given a _single_ expression, it now returns  only  the
number of seconds taken to execute it.

          cmpx'⎕io⊃⎕a'      ⍝ Time single expression.
    1.3E¯6

Technical notes:

Notice in the coding of this function, that name conflicts are avoided by having
the  subject  expression timings execute statically _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{
            ⍬⍴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

See also: time mdf ticks cf

Back to: contents

Back to: Workspaces

Trouble seeing APL font?