What it costs.

One PostgreSQL, three questions: does KealSql cost anything on the way to the database, and what does Keal inside the server cost against its neighbours, on arithmetic and on text. Every number is the best of three runs, on the machine named; the procedure is bench/run.sh, and the reading is in bench/README.md.

Machine : aarch64, 6 cores, Linux, PostgreSQL 18.6 (Ubuntu 18.6-0ubuntu0.26.04.1), keal 1.3.0

On the way to the database

The same query, 20 000 times on one connection: psql running EXECUTE from a script, the KealSql client — a Keal program over libpq — and a C program over libpq, prepared once or sending the text every time. The three prepared paths are within the run-to-run noise of each other (ten to twenty percent on a virtual machine): the time is the round trip and the server, and the client adds nothing that can be measured. Sending the SQL as text each time costs a quarter more — that is what preparing buys, and what the compiler does for every query.

psql EXECUTE, one script
1 234 ms · 1.5×
KealSql client (Keal, libpq)
843 ms · 1×
C over libpq, prepared
967 ms · 1.1×
C over libpq, text each time
2 840 ms · 3.4×

Inside the server, on arithmetic

steps(n), the Collatz count, over 300 000 rows: the same loop as a Keal stored func — compiled through C into a LANGUAGE C function — in PL/pgSQL, and hand-written in C. Keal is about twenty times faster than PL/pgSQL and about two and a half times slower than the C: the difference is Keal's checked arithmetic and its loop, not the bridge, since an integer crosses as an integer.

plkeal (Keal, LANGUAGE C)
193 ms · 1.3×
PL/pgSQL
4 162 ms · 27.6×
C, hand-written
151 ms · 1×

Inside the server, on text

vowels(s), a loop over the forty characters of each of 300 000 rows: Keal, PL/pgSQL, the SQL builtin translate(), and C. Keal is four times faster than PL/pgSQL and twenty times slower than C: iterating a string in Keal hands out one small string per character, a cost of the language measured elsewhere too — a loop over characters is where Keal is slowest. And translate() in one SQL expression beats the loop three to one: when a builtin does the job, use the builtin; KealSql exposes them.

plkeal (Keal, LANGUAGE C)
1 011 ms · 16.3×
PL/pgSQL
3 514 ms · 56.7×
SQL, translate()
315 ms · 5.1×
C, hand-written
62 ms · 1×

Other servers: on the way to the database

The same 20 000 calls on three servers, each from its own C API with the statement prepared once — the compiler out of the picture, the servers face to face. PostgreSQL 18 and MariaDB 11.8 answer over a socket and cost about the same; SQLite runs inside the calling process, so there is no round trip at all, and it is six times faster — that is what being embedded buys, and what it costs is everything a server does for several programs at once.

PostgreSQL 18, libpq
2 254 ms · 5.7×
MariaDB 11.8, libmariadb
2 400 ms · 6.1×
SQLite 3.46.1, in the process
394 ms · 1×

Other servers: inside the database

The same Collatz loop over 300 000 rows in each server's own procedural language: Keal and PL/pgSQL on PostgreSQL, a SQL/PSM function on MariaDB, and on SQLite a C function the program registers, since SQLite has no stored functions of its own. MariaDB's interpreter is seven times slower than PL/pgSQL; Keal on PostgreSQL is a hundred and forty times faster than MariaDB's function and within three of SQLite's C. The three servers are checked to agree on the result before they are timed.

PostgreSQL, plkeal (Keal)
243 ms · 2.6×
PostgreSQL, PL/pgSQL
4 904 ms · 52.7×
MariaDB, SQL/PSM function
34 195 ms · 367.7×
SQLite, a C function of the program
93 ms · 1×

The comparison with other servers measures those servers, not this compiler: KealSql compiles to PostgreSQL and runs on nothing else. It is here because the question is asked, and because the answer says where PostgreSQL stands.