Skip to content

Benchmarks

Three Python packages parse DPM-XL. pydpm-xl and dpmcore validate rules against a DPM database; dpm-xl evaluates rules against report data and explains failures. The table shows where they overlap and where they differ.

Capabilities

dpm-xl pydpm-xl dpmcore
Licence MIT GPL-3.0-or-later Apache-2.0
Runtime dependencies none 8 (pandas, SQLAlchemy, database drivers) antlr4, SQLAlchemy
Parses every EBA 3.4–4.4 rule yes yes yes
Syntax errors plain words with position ANTLR messages ANTLR messages
Evaluates rules against report data yes no no
Explains failing records yes no no
Columnar evaluation for millions of rows yes no no
CLI to evaluate rules on a data file yes no no
Tokenizer and editor grammar yes no no
Outside dpm-xl's scope:
Semantic validation against a DPM release no yes yes
DPM database migration, REST API no migration yes
Reads report files via dpm-xbrl no no

Use pydpm-xl or dpmcore to check that a rule fits a DPM release; use dpm-xl to check that a report satisfies the rules, and why not. The two combine.

Results

The corpus holds the 14,174 distinct rule and precondition expressions of EBA DPM releases 3.4 to 4.4. All three packages reject the same two, which contain typos in the EBA source.

Measured on 2026-10-24 on AMD Ryzen 7 4700U with Radeon Graphics, 8 cores, Linux 7.0.0-38-generic; Python 3.12.3. Best of 3 warm runs; peak RSS over those runs.

Speed and footprint

dpm-xl 1.0.0 pydpm-xl 0.3.12 dpmcore 0.2.1
Syntax check of the corpus (whole process) 1.61 s, 23 MB 14.85 s, 109 MB 15.23 s, 113 MB
Per expression 113 µs 1,047 µs 1,075 µs
import (whole process) 0.09 s, 18 MB 0.75 s, 97 MB 0.85 s, 101 MB
Installed environment 1 distributions, 1 MB 17 distributions, 142 MB 15 distributions, 143 MB

Coverage of the EBA corpus

dpm-xl 1.0.0 pydpm-xl 0.3.12 dpmcore 0.2.1
Expressions accepted 14,172 of 14,174 14,172 of 14,174 14,172 of 14,174
Rejected with {default: 0, interval: true}:if sum({tC_08.01.a, r0070…
with {tV_03.01, default: null, interval: false}: if not(isn…
with {default: 0, interval: true}:if sum({tC_08.01.a, r0070…
with {tV_03.01, default: null, interval: false}: if not(isn…
with {default: 0, interval: true}:if sum({tC_08.01.a, r0070…
with {tV_03.01, default: null, interval: false}: if not(isn…

DPM-XL constructs beyond the EBA rules

dpm-xl 1.0.0 pydpm-xl 0.3.12 dpmcore 0.2.1
rank over a partition accepted rejected accepted
windowed aggregate accepted rejected accepted
statements with := accepted rejected rejected
persistent assignment <- accepted rejected accepted
operation reference accepted accepted accepted
set operators and literals accepted rejected accepted
typed parameter accepted rejected accepted
text concatenation & accepted accepted accepted
date functions accepted rejected accepted
date() and date literals accepted rejected accepted
table group accepted accepted accepted
annualise accepted rejected accepted

Syntax error messages

{tC_01.00, r0010, c0010} >=

  • dpm-xl: expression ends where an operand is expected at position 27
  • pydpm-xl: offendingSymbol: [@11,27:26='',<-1>,1:27] msg: mismatched input '' expecting {BOOLEAN_LITERAL, NOT,…
  • dpmcore: Unexpected error: "offendingSymbol: [@11,27:26='',<-1>,1:27] msg: mismatched input '' expecting {BO…

with {tC_01.00, c0010}: {r0010} = {r0020} +

  • dpm-xl: expression ends where an operand is expected at position 43
  • pydpm-xl: offendingSymbol: [@21,43:42='',<-1>,1:43] msg: mismatched input '' expecting {BOOLEAN_LITERAL, NOT,…
  • dpmcore: Unexpected error: "offendingSymbol: [@21,43:42='',<-1>,1:43] msg: mismatched input '' expecting {BO…

Method

Each package runs in its own virtual environment from PyPI (dpm-xl from this repository), as a separate process through its public syntax-check API: one warm-up, then the best of three runs, with peak memory. Ratios between the packages are more stable than absolute times. Scripts and instructions are in benchmarks/.