1

I was doing a performance test for CWAC-Saferoom, to see how bad it would affect performance in accessing the database.

I created two applications, all their code is identical, except for this:

    private val dbName = "Encrypted_Database"
    private val dbPassword = "Test_Password"

    override val repositoryFactory: IRepositoryFactory by lazy {
        RepositoryFactory(this)
    }

    override val safeHelperFactory: SafeHelperFactory by lazy {
        SafeHelperFactory.fromUser(Editable.Factory.getInstance().newEditable(dbPassword))
    }

    override val database: Database by lazy {
        if (SQLCipherUtils.getDatabaseState(context, dbName) == SQLCipherUtils.State.UNENCRYPTED) { SQLCipherUtils.encrypt(context, dbName, dbPassword.toCharArray()) }

        Room.databaseBuilder(context, Database::class.java, dbName)
            .fallbackToDestructiveMigration()
            .openHelperFactory(safeHelperFactory)
            .build()
    }

As expected, the other application did not have any SQLCipher/SafeHelperFactory utils. It was a simple RoomDB as we all know it.

This is where things start to get interesting.

After measuring the execution time of the functions, I found out that, while using saferoom, the application was SIGNIFICATLY faster in accessing the database!

I created 500,000 random objects with random attributes, and tried inserting them all in both DBs.

  • Room without Saferoom = took roughly 45 seconds.

  • Room with Saferoom = took roughly 15 seconds.

I also did some other testing, and got these results, with less random objects, this time the results were very mixed and within margin of error, as you can check in the picture below:

Now, I'm stuck trying to wrap my head around these results. Has anyone experienced a similar thing? This was not at all what I was expecting. Perhaps my method of measuring is flawed?

Thank you, and if this is the wrong 'overflow' to put this discussion, pardon! :)

Edit: Measuring method at function level

            detailedDishRepository.insertAll(dishes)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe {
                    timeStart = System.nanoTime()
                }
                .doAfterTerminate {
                    val elapsedTime = (System.nanoTime() - timeStart) / 1_000_000_000.0
                    insertTime.value = elapsedTime
                    println("It took $elapsedTime seconds to execute.")
                }
                .subscribe({
                    itemIds.value = it
                }, {
                    println(it.printStackTrace())
                })
                .apply { 
                    disposableList.add(this) 
                }

  • tested on what? [you know that old android versions has old SQLite ?](https://stackoverflow.com/questions/2421189/version-of-sqlite-used-in-android) and SQLCipher 4.2 is using 3.28.0 – Selvin Sep 05 '19 at 13:56
  • @Selvin I tested on an emulator using API 28. I've updated the question to show you how I measured the times of execution. I save those results in a list and then do an average. Does this answer your question? – Rui Almeida Sep 05 '19 at 14:00
  • My guess is that you are seeing changes in SQLite, as SQLCipher for Android is using a newer SQLite than your device probably has in its framework classes. I feel quite confident that SafeRoom itself has little to do with it, as it is just a thin adapter between the `SupportSQLite*` APIs and SQLCipher for Android. – CommonsWare Sep 05 '19 at 14:33
  • The device is using 3.22.0 SQLite version checked by using this post. Not sure how to check the SQLCipher version now, though, a quick search did not yield anything, except for the changelogs, which point to SQLite v3.28, according to the most recent release. – Rui Almeida Sep 05 '19 at 15:11

0 Answers0