Use nullptr.cast() instead of nullptr

This can speed up performance when binding strings
This commit is contained in:
Simon Binder 2019-12-13 23:15:16 +01:00
parent 1672eacb69
commit 2d1d899c71
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
6 changed files with 51 additions and 5 deletions

View File

@ -9,3 +9,11 @@ extension FreePointerExtension on Pointer {
ffi.free(this);
}
}
/// Loads a null-pointer with a specified type.
///
/// The [nullptr] getter from `dart:ffi` can be slow due to being a
/// `Pointer<Null>` on which the VM has to perform runtime type checks. See also
/// https://github.com/dart-lang/sdk/issues/39488
@pragma('vm:prefer-inline')
Pointer<T> nullPtr<T extends NativeType>() => nullptr.cast<T>();

View File

@ -37,7 +37,7 @@ class Database {
final pathC = CBlob.allocateString(fileName);
final resultCode =
bindings.sqlite3_open_v2(pathC, dbOut, _openingFlags, nullptr.cast());
bindings.sqlite3_open_v2(pathC, dbOut, _openingFlags, nullPtr());
final dbPointer = dbOut.value;
dbOut.free();
@ -96,7 +96,7 @@ class Database {
final errorOut = allocate<Pointer<CBlob>>();
final result =
bindings.sqlite3_exec(_db, sqlPtr, nullptr, nullptr, errorOut);
bindings.sqlite3_exec(_db, sqlPtr, nullPtr(), nullPtr(), errorOut);
sqlPtr.free();
@ -123,7 +123,7 @@ class Database {
final sqlPtr = CBlob.allocateString(sql);
final resultCode =
bindings.sqlite3_prepare_v2(_db, sqlPtr, -1, stmtOut, nullptr.cast());
bindings.sqlite3_prepare_v2(_db, sqlPtr, -1, stmtOut, nullPtr());
sqlPtr.free();
final stmt = stmtOut.value;

View File

@ -113,7 +113,7 @@ class PreparedStatement {
final ptr = CBlob.allocateString(param);
_allocatedWhileBinding.add(ptr);
bindings.sqlite3_bind_text(_stmt, i, ptr, -1, nullptr);
bindings.sqlite3_bind_text(_stmt, i, ptr, -1, nullPtr());
} else if (param is Uint8List) {
// avoid binding a null-pointer, as sqlite would treat that as NULL
// in sql which is different from x''
@ -124,7 +124,7 @@ class PreparedStatement {
assert(!ptr.isNullPointer);
_allocatedWhileBinding.add(ptr);
bindings.sqlite3_bind_blob(_stmt, i, ptr, param.length, nullptr);
bindings.sqlite3_bind_blob(_stmt, i, ptr, param.length, nullPtr());
}
}
}

View File

@ -16,6 +16,7 @@ dependencies:
dev_dependencies:
test: ^1.6.0
path: ^1.6.0
benchmark_harness: ^1.0.0
flutter:
plugin:

View File

@ -0,0 +1,26 @@
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:moor_ffi/database.dart';
class SelectStringBenchmark extends BenchmarkBase {
SelectStringBenchmark() : super('SELECT a string variable');
PreparedStatement statement;
Database database;
@override
void setup() {
database = Database.memory();
statement = database.prepare('SELECT ?;');
}
@override
void run() {
statement.select(const ['hello sqlite, can you return this string?']);
}
@override
void teardown() {
statement.close();
database.close();
}
}

View File

@ -0,0 +1,11 @@
import 'benchmark/select_string_variable.dart';
void main() {
final benchmarks = [
SelectStringBenchmark(),
];
for (final benchmark in benchmarks) {
benchmark.report();
}
}