CREATE TABLE store(key TEXT PRIMARY KEY, value TEXT)
Here are the results before I made that change: sqlite
Took 0.032 seconds, 3.19541 microseconds / record
dict_open
Took 0.002 seconds, 0.20261 microseconds / record
dbm_open
Took 0.043 seconds, 4.26550 microseconds / record
sqlite3_mem_open
Took 2.240 seconds, 224.02620 microseconds / record
sqlite3_file_open
Took 7.119 seconds, 711.87410 microseconds / record
And here's what I got after adding the primary keys: sqlite
Took 0.040 seconds, 3.97618 microseconds / record
dict_open
Took 0.002 seconds, 0.19641 microseconds / record
dbm_open
Took 0.042 seconds, 4.18961 microseconds / record
sqlite3_mem_open
Took 0.116 seconds, 11.58359 microseconds / record
sqlite3_file_open
Took 5.571 seconds, 557.13968 microseconds / record
My code is here: https://gist.github.com/simonw/019ddf08150178d49f4967cc38356...Fixing that on my machine took the sqlite3_file_open benchmark from 16.910 seconds to 1.033 seconds. Adding the index brought it down to 0.040 seconds.
Also, I've never really dug into what's going on, but the dbm implementation is pretty slow on Windows, at least when I've tried to use it.
Sure, mutating data sets might be a useful use case. But, inserting thousands of items at once one at a time in a tight loop, then asking for all of them is testing an unusual use case in my opinion.
My point was that we're comparing apples and oranges. By default, I think, Python's dbm implementation doesn't do any sort of transaction or even sync after every insert, where as SQLite does have a pretty hefty atomic guarantee after each INSERT, so they're quite different actions.
Seems like this would be why: https://news.ycombinator.com/item?id=32852333
No kidding.
https://github.com/python/cpython/blob/main/Lib/dbm/dumb.py
It uses a text file to store keys and pointers into a binary file for values. It works .. most of the time .. but yeah, that's not going to win any speed awards.