SQlite: Benchmark

Table of Contents

1. SQlite: Benchmark

分别使用 c,java 程序插入 10w 条记录, 设置 synchronous 为 full 或 off, 保存数据库文件到 sdcard 或 mtd 设备. java 程序使用 execSQL 或 InsertHelper.

  • java 测试程序
private void writeDatabase() {
    // mtd test: use /data/test.db to  mtd
    // sd test: use  /storage/sdcard1/test.db
    SQLiteDatabase db = SQLiteDatabase.openDatabase("/data/test.db", null,SQLiteDatabase.OPEN_READWRITE, null);
    // synchronous = full
    // synchronous = off
    db.execSQL("pragma synchronous=full");
    long startTime=System.currentTimeMillis();
    InsertHelper helper=new InsertHelper(db, "test");
    ContentValues values=new ContentValues();
    values.put("name", "test");
    values.put("count", 3);
    int commit_time=0;
    int exec_time=0;
    for (int i = 0; i < 10; i++) {
        long time1=System.currentTimeMillis();
        db.beginTransaction();
        for (int j = 0; j < 10000; j++) {
            // execSQL test
            // db.execSQL("insert into test values (\"test\",2)");

            // InsertHelper
            helper.insert(values);
        }
        db.setTransactionSuccessful();
        long time2=System.currentTimeMillis();
        db.endTransaction();
        long time3=System.currentTimeMillis();

        exec_time+=(time2-time1);
        commit_time+=(time3-time2);
    }
    long endTime=System.currentTimeMillis();
    Log.e("sunway","done: all_time: "+(endTime-startTime)+"mss avg_exec_time: "+exec_time/10 +"ms "+" avg_commit_time: "+commit_time/10+"ms");

}


  • c 测试程序
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= test_sqlite.c
LOCAL_CFLAGS := -Wno-error-unused-parameter
LOCAL_MODULE:= test_sqlite
LOCAL_MULTILIB := 32

# LOCAL_LDFLAGS := ...
# LOCAL_C_INCLUDES := ...
# LOCAL_STATIC_LIBRARIES := ...
LOCAL_SHARED_LIBRARIES := libsqlite

include $(BUILD_EXECUTABLE)
#include "sqlite3.h"
#include <pthread.h>
#include <string.h>
#include <stdio.h>

void insert(sqlite3 * db) {
    char * zerr;
    int rc=0;
    rc=sqlite3_exec(db,"pragma synchronous=full;",0,0,&zerr);

    struct timeval tv;
    int begin=0;
    int end=0;
    int exec_time=0;
    int commit_time=0;

    int j=0;

    gettimeofday(&tv,NULL);
    begin=tv.tv_sec*1000+tv.tv_usec/1000;

    for (j=0; j<10; j++) {
        gettimeofday(&tv,NULL);
        int time1=tv.tv_sec*1000+tv.tv_usec/1000;

        rc=sqlite3_exec(db,"begin transaction",0,0,&zerr);
        char * sql="insert into test values (?1, ?2)";
        sqlite3_stmt *stmt;
        const char * tail;
        rc=sqlite3_prepare_v2(db, sql, strlen(sql), &stmt,&tail);
        int i=0;
        for (i = 0; i < 10000; ++i) {
            sqlite3_bind_text(stmt, 1, "test", strlen("text"), SQLITE_TRANSIENT);
            sqlite3_bind_int(stmt, 2,1);
            sqlite3_step(stmt);
            sqlite3_reset(stmt);
        }
        gettimeofday(&tv,NULL);
        int time2=tv.tv_sec*1000+tv.tv_usec/1000;

        rc=sqlite3_exec(db,"end transaction",0,0,&zerr);

        gettimeofday(&tv,NULL);
        int time3=tv.tv_sec*1000+tv.tv_usec/1000;
        sqlite3_finalize(stmt);
        exec_time+=(time2-time1);
        commit_time+=(time3-time2);
    }
    gettimeofday(&tv,NULL);
    end=tv.tv_sec*1000+tv.tv_usec/1000;

    printf("done: total_time: %d ms, avg_exec_time: %d ms, avg_commit_time: %d ms\n", end-begin, exec_time/10, commit_time/10);
}


int main(int argc, char *argv[]) {
    sqlite3 *db;
    sqlite3_open_v2("/data/test.db", &db, SQLITE_OPEN_READWRITE, 0);

    pthread_t tid;
    pthread_create(&tid, NULL, insert, db);
    pthread_join(tid, NULL);

    return 0;
}

synchronous storage method total_time (ms) avg_exec_time (ms) avg_commit_time (ms)
off sd c 2002 172 27
off mtd c 1888 163 25
full sd c 3641 165 198
full mtd c 1913 158 31
full ssd c 450 19 25
off sd java/execSQL 12996 1269 29
off sd java/insertHelper 10458 1029 16
off mtd java/insertHelper 10067 977 29
full sd java/execSQL 15385 1252 285
full sd java/insertHelper 11874 987 199
full mtd java/insertHelper 9948 963 31
  • 总结
    • 使用 java api 测试时, 执行 sql 语句的速度比 c 程序慢 7 倍左右
    • insertHelper 比普通的 execSQL 有 20% 的提升
    • java api 和 c api 在 commit 时间上没有差别
    • 在 sd 卡上, synchronous off 有近 10 倍的性能提长
    • 在 mtd 上, synchronous 似乎没有差别.

Author: [email protected]
Date:
Last updated: 2022-01-14 Fri 12:57

知识共享许可协议