Version 14.0 Performance

Despite the large number of new features in version 14.0, there has also been time to optimise a large number of primitives, and a few core algorithms that are widely used within the interpreter. A summary of tuned features can be found in the version 14.0 Release Notes and the on-line help.

The chart on the right shows the output from our internal performance monitor, an application that times 14,000 different expressions and compares them to times from earlier versions: the blue area represents expressions which have speeded up. Although there are expressions that have slowed down, the blue are is very significantly larger (note that the blue area is truncated at above +20%): many of the expressions with the largest speed-ups are widely used. Several beta testers reported application benchmark speed-ups of between 10 and 30 percent, compared to v13.2.

Futures and Isolates

Futures and Isolates are experimental language extensions that are intended to provide the developer with ways to express the existence of potentially parallel sections of code in a deterministic fashion.

  • An isolate is a namespace that is semantically equivalent to a normal namespace, except that expressions which are executed inside an isolate can run in parallel (in a separate process) to the main application process.
  • A future is an array of unknown rank, shape and content, which is returned as the result of any expression that is executed inside an isolate. Futures can be passed as arguments to user-defined functions or nested to form arrays containing several futures, without blocking. Arrays containing futures can also be subjected to structural transformations such as reshape or partitioned enclose, without blocking. Blocking occurs when one or more futures are passed to a function which needs to know the actual value (for example, a mathematical primitive function).

Between them, futures and isolates make it straightforward to divide application code into sections that can run in parallel: if one function requires the result of code which is still executing in parallel, the dependent function will automatically wait until the data that it needs is available.

Dyalog Experimental Functionality – Parallel Language Features

Compiler

Version 14.0 contains the first experimental version of a compiler, which has the potential to significantly increase the performance of Dyalog applications in the years to come. In version 14.0 the compiler is restricted to working only on functions and operators that are written in a purely functional style; that is, functions and operators that:

  • do not rely on any global or semi-global variables
  • do not have any side effects.
  • apply some calculations to their arguments and return a result

At present, the compiler converts functions into bytecode, which eliminates most of the overhead of interpreting APL expressions at runtime. The biggest performance gains (a factor of roughly 2) are achieved when the compiler is used on functions that are applied to simple scalars or small array arguments. If the arguments are large arrays, then the interpreter spends most of its time actually executing primitives.

In future releases, the compiler will be extended to support more application code and perform a number of optimisations beyond simply removing interpreter overhead.

Dyalog Experimental Functionality – Compiler