Skip to content

Performance benchmark #163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ linter:
# additional rules used by pub.dev
non_constant_identifier_names: true

# exclude standalone packages:
analyzer:
exclude:
- example/**
- generator/** # needs to be checked separately because its a separate package
- generator/**
- benchmark/**
12 changes: 12 additions & 0 deletions benchmark/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Files and directories created by pub
.dart_tool/
.packages

# Conventional directory for build outputs
build/

# Directory created by dartdoc
doc/api/

# ObjectBox DB files
**.mdb
57 changes: 57 additions & 0 deletions benchmark/bin/benchmark.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'dart:io';

import 'package:args/args.dart';
import 'package:glob/glob.dart';
import 'package:objectbox_benchmark/benchmark.dart';

void main(List<String> arguments) {
exitCode = 0; // presume success

final argDb = 'db';
final argCount = 'count';
final argRuns = 'runs';

final parser = ArgParser()
..addOption(argDb, defaultsTo: 'benchmark-db', help: 'database directory')
..addOption(argCount, defaultsTo: '10000', help: 'number of objects')
..addOption(argRuns,
defaultsTo: '30', help: 'number of times the tests should be executed');

final args = parser.parse(arguments);
final dbDir = Directory(args[argDb]);
final count = int.parse(args[argCount]);
final runs = int.parse(args[argRuns]);

print('running $runs times with $count objects in $dbDir');

if (dbDir.existsSync()) {
print('deleting existing DB files in $dbDir');
final dbFilesGlob = Glob(dbDir.path + '/*.mdb');
for (var dbFile in dbFilesGlob.listSync()) {
dbFile.deleteSync();
}
}

final bench = Executor(dbDir);

final inserts = bench.prepareData(count);

for (var i = 0; i < runs; i++) {
bench.putMany(inserts);
final items = bench.readAll();
bench.changeValues(items);
bench.updateAll(items);
bench.removeAll();

print('${i + 1}/$runs finished');
}

bench.close();
bench.printTimes([
'putMany',
'readAll',
'updateAll',
'removeAll',
]);
}

84 changes: 84 additions & 0 deletions benchmark/lib/benchmark.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import 'dart:io';

import 'package:objectbox/objectbox.dart';

import 'model.dart';
import 'objectbox.g.dart';

class Executor {
final Store store;

/*late final*/
Box<TestEntity> box;

/// list of runtimes indexed by function name
final times = <String, List<Duration>>{};

Executor(Directory dbDir)
: store = Store(getObjectBoxModel(), directory: dbDir.path) {
box = Box<TestEntity>(store);
}

void close() => store.close();

R _track<R>(String fnName, R Function() fn) {
final watch = Stopwatch();

watch.start();
final result = fn();
watch.stop();

times[fnName] ??= <Duration>[];
times[fnName].add(watch.elapsed);
return result;
}

void _print(List<dynamic> varArgs) {
print(varArgs.join('\t'));
}

void printTimes([List<String> functions]) {
functions ??= times.keys.toList();

// print the whole data as a table
_print(['Function', 'Runs', 'Average ms', 'All times']);
for (final fun in functions) {
final fnTimes = times[fun];

final sum = fnTimes.map((d) => d.inMicroseconds).reduce((v, e) => v + e);
final avg = sum.toDouble() / fnTimes.length.toDouble() / 1000;
final timesCols = fnTimes.map((d) => d.inMicroseconds.toDouble() / 1000);
_print([fun, fnTimes.length, avg, ...timesCols]);
}
}

List<TestEntity> prepareData(int count) {
return _track('prepareData', () {
final result = <TestEntity>[];
for (var i = 0; i < count; i++) {
result.add(TestEntity.full('Entity #$i', i, i, i.toDouble()));
}
return result;
});
}

void putMany(List<TestEntity> items) {
_track('putMany', () => box.putMany(items));
}

void updateAll(List<TestEntity> items) {
_track('updateAll', () => box.putMany(items));
}

List<TestEntity> readAll() {
return _track('readAll', () => box.getAll());
}

void removeAll() {
_track('removeAll', () => box.removeAll());
}

void changeValues(List<TestEntity> items) {
_track('changeValues', () => items.forEach((item) => item.tLong *= 2));
}
}
20 changes: 20 additions & 0 deletions benchmark/lib/model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:objectbox/objectbox.dart';

@Entity()
class TestEntity {
@Id()
int /*?*/ id;

String /*?*/ tString;

@Property(type: PropertyType.int)
int /*?*/ tInt; // 32-bit

int /*?*/ tLong; // 64-bit

double /*?*/ tDouble;

TestEntity();

TestEntity.full(this.tString, this.tInt, this.tLong, this.tDouble);
}
51 changes: 51 additions & 0 deletions benchmark/lib/objectbox-model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
"entities": [
{
"id": "1:1824294286181366916",
"lastPropertyId": "5:5062831200094422416",
"name": "TestEntity",
"properties": [
{
"id": "1:725236837183566145",
"name": "id",
"type": 6,
"flags": 1
},
{
"id": "2:3060128101942237916",
"name": "tString",
"type": 9
},
{
"id": "3:3092165041934597703",
"name": "tInt",
"type": 5
},
{
"id": "4:4958684909838795382",
"name": "tLong",
"type": 6
},
{
"id": "5:5062831200094422416",
"name": "tDouble",
"type": 8
}
]
}
],
"lastEntityId": "1:1824294286181366916",
"lastIndexId": "0:0",
"lastRelationId": "0:0",
"lastSequenceId": "0:0",
"modelVersion": 5,
"modelVersionParserMinimum": 5,
"retiredEntityUids": [],
"retiredIndexUids": [],
"retiredPropertyUids": [],
"retiredRelationUids": [],
"version": 1
}
18 changes: 18 additions & 0 deletions benchmark/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: objectbox_benchmark
description: Simple ObjectBox-Dart performance benchmark

environment:
sdk: ">=2.6.0 <3.0.0"

dependencies:
objectbox: any

dev_dependencies:
objectbox_generator: any
build_runner: ^1.0.0

dependency_overrides:
objectbox:
path: ../
objectbox_generator:
path: ../generator