hive icon indicating copy to clipboard operation
hive copied to clipboard

Benchmark trick?

Open xanahopper opened this issue 2 years ago • 0 comments

Question Sqflite benchmark doesn't use batch or transaction,meanings 1000 iterations performs 1000 transaction.

I switch Sqflite's benchmark to batch, it seems better than before and better than hive on write.

image image

Code sample

// sqlite_store.dart
class SqfliteStore {
  static const String TABLE_NAME_STR = "kv_str";
  static const String TABLE_NAME_INT = "kv_int";
  late Database db;
  late Batch batch;

  Future init() async {
    var dir = await getApplicationDocumentsDirectory();
    var dbPath = path.join(dir.path, 'sqlite.db');
    if (await File(dbPath).exists()) {
      await File(dbPath).delete();
    }
    db = await openDatabase(
      dbPath,
      onCreate: (db, version) async {
        await db.execute(
          'CREATE TABLE $TABLE_NAME_STR (key TEXT PRIMARY KEY, value TEXT)',
        );
        await db.execute(
          'CREATE TABLE $TABLE_NAME_INT (key TEXT PRIMARY KEY, value INTEGER)',
        );
      },
      version: 1,
    );
  }

  void startBatch() {
    batch = db.batch();
  }

  Future<List<Object?>> commitBatch() async {
    return await batch.commit();
  }

  Future<void> getInt(String key) async {
    batch.query(
      TABLE_NAME_INT,
      where: "key = ?",
      whereArgs: [key],
    );
    // return result[0]['value'] as int;
  }

  Future putInt(String key, int value) async {
    batch.insert(
      TABLE_NAME_INT,
      {'key': key, 'value': value},
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  Future deleteInt(String key) async {
    batch.delete(
      TABLE_NAME_INT,
      where: "key = ?",
      whereArgs: [key],
    );
  }

  Future<void> getString(String key) async {
    var result = batch.query(
      TABLE_NAME_STR,
      where: "key = ?",
      whereArgs: [key],
    );
  }

  Future putString(String key, String value) async {
    batch.insert(
      TABLE_NAME_STR,
      {'key': key, 'value': value},
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  Future deleteString(String key) async {
    batch.delete(
      TABLE_NAME_STR,
      where: "key = ?",
      whereArgs: [key],
    );
  }

  Future close() {
    return db.close();
  }
}
/// sqflite.dart
class SqfliteRunner implements BenchmarkRunner {
  late SqfliteStore store;

  @override
  String get name => 'sqflite';

  @override
  Future<void> setUp() async {
    store = SqfliteStore();
    await store.init();
  }

  @override
  Future<void> tearDown() async {
    await store.close();
  }

  @override
  Future<int> batchReadInt(List<String> keys) async {
    var s = Stopwatch()..start();
    store.startBatch();
    for (var key in keys) {
      store.getInt(key);
    }
    await store.commitBatch();
    s.stop();
    return s.elapsedMilliseconds;
  }

  @override
  Future<int> batchReadString(List<String> keys) async {
    var s = Stopwatch()..start();
    store.startBatch();
    for (var key in keys) {
      store.getString(key);
    }
    await store.commitBatch();
    s.stop();
    return s.elapsedMilliseconds;
  }

  @override
  Future<int> batchWriteInt(Map<String, int> entries) async {
    var s = Stopwatch()..start();
    store.startBatch();
    for (var key in entries.keys) {
      store.putInt(key, entries[key]!);
    }
    await store.commitBatch();
    s.stop();
    return s.elapsedMilliseconds;
  }

  @override
  Future<int> batchWriteString(Map<String, String> entries) async {
    var s = Stopwatch()..start();
    store.startBatch();
    for (var key in entries.keys) {
      await store.putString(key, entries[key]!);
    }
    await store.commitBatch();
    s.stop();
    return s.elapsedMilliseconds;
  }

  @override
  Future<int> batchDeleteInt(List<String> keys) async {
    var s = Stopwatch()..start();
    store.startBatch();
    for (var key in keys) {
      await store.deleteInt(key);
    }
    await store.commitBatch();
    s.stop();
    return s.elapsedMilliseconds;
  }

  @override
  Future<int> batchDeleteString(List<String> keys) async {
    var s = Stopwatch()..start();
    store.startBatch();
    for (var key in keys) {
      await store.deleteString(key);
    }
    await store.commitBatch();
    s.stop();
    return s.elapsedMilliseconds;
  }
}

Version

  • Platform: Android, Mac
  • Flutter version: 2.10
  • Hive version: ^2.0.5

xanahopper avatar Aug 24 '22 04:08 xanahopper