内存型SQLite3数据库能否比C++数据结构性能更优?
问题背景与疑问
我有一个管理结构体数组的场景,该数组类似SQL表,需要基于结构体的各类属性执行类SQL查询。我希望使用内存型SQLite3数据库替代C++结构体数组,借助其内置的查询、索引特性减少代码量并提升性能,无需自行实现遍历与索引逻辑。
但初始测试显示,仅插入操作,内存型SQLite3就比C++数据结构慢12-30倍。我尝试过Stack Overflow上的部分优化方案,但效果有限。
我的问题是:内存型SQLite3数据库能否在性能上超过C++数据结构?
注:由于插入与查询操作实时交错,我无法采用批量插入、先插入后建索引等优化方式,仅希望SQLite的算法优化能在查询性能上超越自行实现的C++数据结构(例如基于prop3和prop5查询时,无需自行实现索引)。
使用C++数据结构的示例代码
#include <iostream> #include <map> #include <cstdlib> #include <ctime> struct item_t { unsigned int a; unsigned int b; bool prop1; bool prop2; bool prop3; bool prop4; bool prop5; }; typedef std::map<unsigned int, item_t> items_t; int main() { srand(RAND_SEED); items_t data; unsigned int delta = 0x100000000 / ITERATIONS, randInt; unsigned int count; // 创建ITERATIONS个带随机属性的条目 for (unsigned int i = 0, a = 0; i < ITERATIONS; ++i, a += delta) { randInt = rand(); data[a] = { a, a + delta - 1, bool(randInt & 16), bool(randInt & 8), bool(randInt & 4), bool(randInt & 2), bool(randInt & 1) }; } printf("Inserted %d entries\n", data.size()); return 0; }
使用内存型SQLite3数据库的示例代码
#include <stdio.h> #include <ctime> #include <cstdlib> #include <sqlite3.h> #include <cassert> #include <string.h> static int sqliteExecCallback(void *unused, int count, char **data, char **columns) { for (int idx = 0; idx < count; idx++) { printf("%s\n", data[idx]); } return 0; } int main() { srand(RAND_SEED); unsigned int delta = 0x100000000 / ITERATIONS, randInt; sqlite3 *db; char *zErrMsg = 0; int rc; rc = sqlite3_open(":memory:", &db); if (rc) { fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db)); return(0); } rc = sqlite3_exec( db, "PRAGMA synchronous = OFF;" "PRAGMA journal_mode = MEMORY", NULL, NULL, &zErrMsg ); if (rc) { fprintf(stderr, "无法设置PRAGMA参数: %s\n", sqlite3_errmsg(db)); return(0); } rc = sqlite3_exec( db, "CREATE TABLE IF NOT EXISTS DATA(" "a INTEGER PRIMARY KEY," "b INTEGER," "prop1 INTEGER," "prop2 INTEGER," "prop3 INTEGER," "prop4 INTEGER," "prop5 INTEGER" ");" "CREATE INDEX DATA_prop1_idx on DATA(prop1);" "CREATE INDEX DATA_prop2_idx on DATA(prop2);" "CREATE INDEX DATA_prop3_idx on DATA(prop3);" "CREATE INDEX DATA_prop4_idx on DATA(prop4);" "CREATE INDEX DATA_prop5_idx on DATA(prop5);", 0, 0, &zErrMsg ); if (rc) { fprintf(stderr, "无法执行建表语句: %s\n", sqlite3_errmsg(db)); return(0); } char sql[512] = "INSERT INTO DATA (a, b, prop1, prop2, prop3, prop4, prop5)"; int len = strlen(sql); for (unsigned int i = 0, a = 0; i < ITERATIONS; ++i, a += delta) { randInt = rand(); sprintf( sql + len, " VALUES (%u, %u, %d, %d, %d, %d, %d);", a, a + delta - 1, bool(randInt & 16), bool(randInt & 8), bool(randInt & 4), bool(randInt & 2), bool(randInt & 1) ); rc = sqlite3_exec(db, sql, 0, 0, &zErrMsg); } rc = sqlite3_exec(db, "SELECT COUNT(*) FROM DATA", sqliteExecCallback, 0, &zErrMsg); if (false && rc) { fprintf(stderr, "无法执行COUNT查询: %s\n", sqlite3_errmsg(db)); } return 0; }
编译与运行命令
g++ -std=c++20 -O3 -march=native -DITERATIONS=2000000 -DRAND_SEED=1 sqlite.cpp -l sqlite3 > comp.log 2>&1 /bin/time -f "sqlite,%S,%U,%e,%M,%X" --append -o metrics.csv ./a.out > run.log 2>&1 g++ -std=c++20 -O3 -march=native -DITERATIONS=2000000 -DRAND_SEED=1 cpp.cpp -l sqlite3 > comp.log 2>&1 /bin/time -f "cpp,%S,%U,%e,%M,%X" --append -o metrics.csv ./a.out > run.log 2>&1
测试运行时长
| 方案 | 系统时间 | 用户时间 | 实际时间 | 最大内存(KB) | 退出状态 |
|---|---|---|---|---|---|
| cpp | 0.09 | 0.62 | 0.71 | 128928.0 | 0.0 |
| sqlite | 0.06 | 25.01 | 25.07 | 196864.0 | 0.0 |
补充说明
注:由于请求来自外部,我无法批量执行SQL查询,但接受其他优化方案。
更新:使用sqlite3_prepare_v2后,性能提升了8倍,运行时间降至3-4秒。
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

