Skip to content

Instantly share code, notes, and snippets.

@avichalp avichalp/benchmarks.md
Last active Feb 23, 2018

Embed
What would you like to do?
Embedded databases benchmarks

@coleifer: Did some simple benchmarking of embedded databases in python. It was done in with the following environment:

  • Linux 3.14.4
  • Python 2.7.7 (Py2K 4 lyfe!)
  • SSD

I have modified his script for python 3.5 and run the script against sd card. My environment is:

  • Linux 4.4.38
  • Python 3.5.2
  • SD card
  • ARM v7

Testing with N = 100000

UnQLite

Writes: 2.444714069366455 Reads: 1.6616613864898682

UnQLiteJSON

Writes: 3.617347478866577 Reads: 2.1200473308563232

Vedis

Writes: 2.357679605484009 Reads: 1.624964714050293

VedisKV

Writes: 2.47371244430542 Reads: 1.6631860733032227

GDBM

Writes: 3.0294344425201416 Reads: 1.49436616897583

BDBBTree

Writes: 8.086156606674194 Reads: 4.68268609046936

BDBHashTable

Writes: 9.237087488174438 Reads: 5.801295757293701

KyotoBTree

Writes: 1.4112212657928467 Reads: 1.4075307846069336

KyotoHashTable

Writes: 1.5034441947937012 Reads: 1.3784515857696533

LevelDB

Writes: 2.7352421283721924 Reads: 1.335801362991333

Sqlite

Writes: 1267.9827723503113 Reads: 7.064197301864624

import os
import time
from unqlite import UnQLite
from vedis import Vedis
import bsddb3
import dbm.gnu as gdbm
import kyotocabinet as kc
import plyvel
import sqlite3
def timed(fn):
def inner(*args):
s = time.time()
fn(*args)
return time.time() - s
return inner
class Test(object):
def __init__(self, n):
self.n = n
if os.path.exists(self.filename):
if os.path.isdir(self.filename):
os.removedirs(self.filename)
else:
os.unlink(self.filename)
self._db = self.get_db()
def close(self):
try:
self._db.close()
except AttributeError:
pass
@timed
def test_writes(self):
for i in range(self.n):
self.write(str(i))
@timed
def test_reads(self):
for i in range(self.n):
self.read(str(i))
def write(self, i):
self._db[i] = i
def read(self, i):
return self._db[i]
class UnQLiteTest(Test):
filename = '/tmp/unq.db'
def get_db(self):
return UnQLite(self.filename)
class UnQLiteJSONTest(Test):
filename = '/tmp/unq-json.db'
def get_db(self):
db = UnQLite(self.filename)
self.coll = db.collection('values')
self.coll.create()
@timed
def test_writes(self):
data = [{str(i): i} for i in range(self.n)]
self.coll.store(data)
@timed
def test_reads(self):
return self.coll.all()
class VedisTest(Test):
filename = '/tmp/vedis.db'
def get_db(self):
return Vedis(self.filename)
class VedisKVTest(Test):
filename = '/tmp/vediskv.db'
def write(self, i):
self._db.store(i, i)
def read(self, i):
return self._db.fetch(i)
def get_db(self):
return Vedis(self.filename)
class GDBMTest(Test):
filename = '/tmp/gdbm.db'
def get_db(self):
return gdbm.open(self.filename, 'c')
class BDBBTreeTest(Test):
filename = '/tmp/bdb_btree.db'
def get_db(self):
return bsddb3.btopen(self.filename)
def write(self, i):
self._db[bytes(i, "utf-8")] = bytes(i, "utf-8")
def read(self, i):
return self._db[bytes(i, "utf-8")]
class BDBHashTableTest(Test):
filename = '/tmp/bdb_hashtable.db'
def get_db(self):
return bsddb3.hashopen(self.filename)
def write(self, i):
self._db[bytes(i, "utf-8")] = bytes(i, "utf-8")
def read(self, i):
return self._db[bytes(i, "utf-8")]
class KyotoBTreeTest(Test):
filename = '/tmp/kyoto_btree.kct'
def get_db(self):
db = kc.DB()
db.open(self.filename, kc.DB.OWRITER | kc.DB.OCREATE)
return db
def write(self, i):
self._db.set(i, i)
def read(self, i):
return self._db.get(i)
class KyotoHashTableTest(Test):
filename = '/tmp/kyoto_hashtable.kch'
def get_db(self):
db = kc.DB()
db.open(self.filename, kc.DB.OWRITER | kc.DB.OCREATE)
return db
def write(self, i):
self._db.set(i, i)
def read(self, i):
return self._db.get(i)
class LevelDBTest(Test):
filename = '/tmp/leveldb.db'
def get_db(self):
return plyvel.DB(self.filename, create_if_missing=True)
def write(self, i):
self._db.put(bytes(i, "utf-8"), bytes(i, "utf-8"))
def read(self, i):
return self._db.get(bytes(i, "utf-8"))
class RocksDBTest(Test):
filename = '/tmp/rocksdb.db'
def get_db(self):
return rocksdb.DB(self.filename,
rocksdb.Options(create_if_missing=True))
def write(self, i):
self._db.put(i, i)
def read(self, i):
self._db.get(i)
class SqliteTest(Test):
filename = '/tmp/sqlite.db'
def get_db(self):
db = sqlite3.connect(self.filename)
self._cursor = db.cursor()
self._cursor.execute("""
create table data (
key varchar(255) not null primary key,
value varchar(255) not null
);
""")
return db
def write(self, i):
self._cursor.execute("INSERT INTO data (key, value) VALUES (?, ?)",
(i, i))
self._db.commit()
def read(self, i):
self._cursor.execute("SELECT * FROM data WHERE key=?", (i,))
self._cursor.fetchall()
class RedisTest(Test):
filename = '/tmp/na'
def get_db(self):
db = Redis(db=15)
db.flushdb()
return db
tests = [
UnQLiteTest,
UnQLiteJSONTest,
VedisTest,
VedisKVTest,
GDBMTest,
BDBBTreeTest,
BDBHashTableTest,
KyotoBTreeTest,
KyotoHashTableTest,
LevelDBTest,
SqliteTest,
]
N = 100000
print('Testing with N = %s' % N )
print( '------------------------------------' )
print('\n\n')
for TestClass in tests:
test_name = TestClass.__name__.replace('Test', '')
print( test_name )
print( '~' * len(test_name))
test = TestClass(N)
print( 'Writes: ', test.test_writes())
print( 'Reads: ', test.test_reads())
print('\n')
test.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.