2

We are seeing a drastic performance loss after using SQLCipher 4.2 in our android app. Even in case we don't provide an encryption key and just use SQLCipher without encryption our app performances about 300 percent slower as if we use the FrameworkSQLite Database. Are there any connection parameter that we could try to change to boost the performance? What is the difference between the native sqlLite engine that is shipped with Android and the one that is used by SqlCipher?

target sdk is 29

the device we are testing on is a samsung T515 tablet we don't see much cpu usage in the profiler

this is how we define import sqlcipher android wrapper:

repositories {
    flatDir {
        dirs 'libs/aars'
    }
}
dependencies {
    ...
    implementation (name:'android-database-sqlcipher-4.2.0-release', ext:'aar')
    ...
} 

this is how we open the database:

public SupportSQLiteOpenHelper getDatabase(final DatabaseIdentifier identifier, final DatabaseDefinition databaseDefinition) throws IOException, GeneralSecurityException {
    SupportSQLiteOpenHelper.Factory factory;
    final int sqliteEngine = databaseDefinition.getSqliteEngine();
    if (sqliteEngine == DatabaseDefinition.SQLITE_ENGINE_ANDROID_FRAMEWORK) {
        factory = new FrameworkSQLiteOpenHelperFactory();
    }
    else if (sqliteEngine == DatabaseDefinition.SQLITE_ENGINE_SQLCIPHER) {
        final SQLiteDatabaseHook sqlCipherHook = new SQLiteDatabaseHook() {
            @Override
            public void preKey(final net.sqlcipher.database.SQLiteDatabase sqLiteDatabase) {
            }
            @Override
            public void postKey(final net.sqlcipher.database.SQLiteDatabase sqLiteDatabase) {
                    sqLiteDatabase.rawExecSQL("PRAGMA cipher_memory_security = OFF;");
            }
        };
        if (databaseDefinition.isSqlCipherEncrypted()) {
            factory = new SupportFactory(databaseDefinition.getSqlCipherEncryptionKey(), sqlCipherHook);
        }
        else {
            factory = new SupportFactory(new byte[0], sqlCipherHook);
        }
    }
    else {
        throw new AssertionError();
    }
    final SupportSQLiteOpenHelper.Callback callback = new SupportSQLiteOpenHelper.Callback(1) {
        @Override
        public void onCreate(final SupportSQLiteDatabase db) {
        }
        @Override
        public void onUpgrade(final SupportSQLiteDatabase db, final int oldVersion, final int newVersion) {
        }
        @Override
        public void onOpen(final SupportSQLiteDatabase db) {
            super.onOpen(db);
            ....
        }
    };
    final SupportSQLiteOpenHelper.Configuration configuration = SupportSQLiteOpenHelper.Configuration
            .builder(mApplication)
            .name(databaseDefinition.getPath())
            .callback(callback)
            .build();
    return factory.create(configuration);
}``` 
  • See https://discuss.zetetic.net/c/sqlcipher and https://discuss.zetetic.net/t/sqlcipher-performance-optimization/14. Beyond that, use Android Studio profiling or logging to determine *precisely* where your time is being spent. – CommonsWare Nov 20 '19 at 12:53
  • One way the performance with SQLCipher differs significantly from the default Android SQLite API is with concurrent database operations. SQLCipher's Android API has a locking behavior that has been improved in the default API since API 16 (Jelly Bean). More details here: https://discuss.zetetic.net/t/android-api-update/3551 – Jeff Lockhart Nov 24 '19 at 05:58

0 Answers0