- 簡単なベンチマークプログラムを用いてインメモリモードとファイルモードのCRUDの性能を比較
概要
ふと「SQLiteってインメモリモードとファイルモードでどれくらい性能差があるのか?」という疑問が浮かんだので、なるべく時間をかけずにベンチマークコードを書いて試してみた。せっかくなので結果を共有する。
結果
単位は秒。10回実施した平均値を示す。
Mac/SSD
機種ID: MacBookPro10,2
プロセッサ名: Intel Core i5
プロセッサ速度: 2.5 GHz
メモリ: 8 GB
# | 操作 | ファイルモード | インメモリモード |
---|---|---|---|
1 | 100万行のbulk-insert | 6.290 | 5.835 |
2 | 1行をinsert | 0.247 | 0.225 |
3 | 文字列カラムでソート | 0.221 | 0.195 |
4 | 数値カラムでソート | 0.238 | 0.175 |
5 | 文字列・数値でフィルタ | 0.008 | 0.007 |
6 | 更新 | 0.130 | 0.086 |
7 | 削除 | 0.186 | 0.127 |
Windows/HDD
プロセッサ: Intel Core i7-7700
プロセッサ速度: 3.6 GHz
メモリ: 32 GB
# | 操作 | ファイルモード | インメモリモード |
---|---|---|---|
1 | 100万行のbulk-insert | 4.655 | 3.417 |
2 | 1行をinsert | 0.285 | 0.132 |
3 | 文字列カラムでソート | 0.209 | 0.185 |
4 | 数値カラムでソート | 0.242 | 0.220 |
5 | 文字列・数値でフィルタ | 0.009 | 0.007 |
6 | 更新 | 0.556 | 0.105 |
7 | 削除 | 0.781 | 0.127 |
ベンチマークコード
Githubで公開している。
- SQLite Benchmark
以下は抜粋。
db.create_all()
sw = StopWatch()
sw.start()
entities = [dict(
text1=random_text(3),
text2=random_text(3),
number1=random(),
number2=random(),
) for i in range(args.records)]
sw.wrap('generate {0} records'.format(args.records))
db.session.execute(ItemMapper.__table__.insert(), entities)
db.session.commit()
sw.wrap('bulk insert {0} records'.format(args.records))
del entities
item = ItemMapper()
item.text1 = 'aaa'
item.text2 = 'bbb'
item.number1 = 0.1
item.number2 = 0.2
db.session.add(item)
db.session.commit()
sw.wrap('insert 1 records')
result1 = ItemMapper.query.order_by(ItemMapper.text1, ItemMapper.text2).offset(1000).limit(20).all()
sw.wrap('select order by text1, text2 offset 1000 limit 20')
result2 = ItemMapper.query.order_by(ItemMapper.number1, ItemMapper.number2).offset(1000).limit(20).all()
sw.wrap('select order by number1, number2 offset 1000 limit 20')
result3 = ItemMapper.query.filter(ItemMapper.text1.startswith('a')) \
.filter(ItemMapper.number1 > 0.5).offset(1000).limit(20).all()
sw.wrap('select where text1 like a* and number1 > 0.5 offset 1000 limit 20')
ItemMapper.query.filter(ItemMapper.text1 == 'aaa').update(dict(text1='bbb'))
db.session.commit()
sw.wrap('update text1 bbb where text1==aaa')
ItemMapper.query.filter(ItemMapper.text1 == 'bbb').delete()
db.session.commit()
sw.wrap('delete where text1 == bbb')
sw.describe()
reports.append(sw.get_report())
db.drop_all()