FFI calling convention for C functions defaults to 'safe' which incurs
a heavy per-call overhead. Use of 'unsafe' should be fine for several
of the sqlite3 column and binding accessors as they do not callback to
Haskell from C. Furthermore, no I/O should be happening in these
accessors, all these functions do is move data over from C land to
The less frequently entry points are left in default 'safe' mode.
This is just a defensive move for future code maintenance.
Performance delta in a synthetic benchmark such as
https://github.com/nurpax/db-bench is significant. Benchmarking the
direct-sqlite 'columns' call, we can see an improvement from 1.2M
rows/sec to 2.9M rows/sec. The nice thing about this is that
direct-sqlite now also beats Python sqlite3 module by about 50%.