Dyalog v14.0: Performance Improvements
Despite the large number of new features in Dyalog v14.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 Dyalog v14.0 Release Notes.
Internal Benchmarks
Internal benchmarking was performed on the initial release of Dyalog v14.0 and the results compared with the initial release of Dyalog v13.2.
The benchmarking process comprises over 13,000 benchmarks in more than 130 groups; the group geometric mean timing ratios are measured and plotted against the groups sorted by their means. The vertical axis of the graph shows the ratios as a percentage change; negative values are shown in blue and indicate a performance enhancement, and positive values are shown in red and indicate a deterioration in performance.
Although there are expressions that have slowed down, the blue area is 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 Dyalog 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 that 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
Dyalog v14.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 Dyalog v14.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.