One goal for Daffodil is efficiency. This goal is second to correctness, because performance can also be obtained by just scaling up hardware. However, a major reason people use non-XML data formats is for data density in high-performance or low-power (aka mobile) applications. So good performance is quite essential to success.
This page is for discussion of various ideas associated with achieving good runtime performance.
Discussion of parallelism/concurrency of processing is also appropriate.
Performance of the daffodil compiler itself is a separate topic.
A major overhead in any JVM-based system is minimizing unnecessary allocation.
This is in tension with parallelism. Often, to operate in parallel requires more storage, not a central reusable data structure.
Abstractly, the runtime is a bunch of functions from PState to PState, and this means every parse operation involves allocating a new PState object. Effectively, the parser behaves like an inner-loop calling the allocator for PState objects. This has the advantage that all code is inherently thread-safe.
Note: except the implementation currently uses JDOM trees as the Infoset representation, and these are mutated. These would have to be replaced by an inverted child-points-to-parent-only pure-functional Infoset representation.
However, this also limits performance to that of the garbage collector, and parallel performance to the ability of the allocator and garbage collector to run in parallel.
The alternative to this is to use a mutable state, and a parser mutates that state. Parallelism then requires the ability to create or obtain exclusive access to a separate state for use by the concurrent parse activity. This state is then passed downward to all parser code (and unparser code), but is updated in place by that code. No return of a PState object.
The runtime generally uses lots of Lists, mostly as stacks of variable bindings, backtrack locations, etc. Instead of these, one can use mutable arrays with current indexes in the state to indicate what is in use. For parallelism, allocating a new state then involves also allocating these mutable arrays.
Alternation and Variables
All variables are declared in DFDL, so each gets an array within the execution state. The DFDL newVariableInstance statement just increments a currentLocation index for its variable.
Input Stream Position
Each backtrack point saves the pos (stack again). Successful advancing pops the stack, but then reassigns top to hold the new position value.
A great deal of runtime overhead is required if Daffodil is to provide good diagnostic messages when things go wrong.
The runtime could have a "no diagnostics" speed-oriented mode. In this mode, no Diagnostic objects would be allocated.