Speed up your KittyORM
KittyORM build with Java7 for Android and main idea is to implement developer-friendly tool that would save your time and money on implementing business logic that needs SQLite database for storing data. KittyORM provides a lot of features that can save your time on developing and supporting your data model, but it uses reflection to avoid messing around with raw SQL code and some tools as generating data model from domain package. And it is not performance free. This tutorial page is kind of FAQ or cookbook of how to tune up your KittyORM implementation to achieve maximum performance. Main idea of this tutorial - use only those features you really need. And now goes list of tips.
Tip №1: Avoid using generating data model from packages
KittyORM supports generating data model from classes that implements KittyModel.class
and KittyMapper.class
. It’s really handy feature, but slow. While generating list of classes in application namespace KittyDexUtils.class
has to scan all classes that exist, check naming rules, get their instances with Class.forName(className, false, context.getClassLoader());
and check if classes are assignable from base model or mapper class, check if their package is domain package, check if those classes suits KittyDexClassFilter.class
instance. It is very performance expensive operation, because typically there are hundreds or even thousands of classes that are available in application namespace.
Use this feature only for development or testing purposes and on production it is better to define your data model with usage of KITTY_DATABASE_REGISTRY
and KITTY_REGISTRY_PAIR
annotations or by initializing static KittyORM registry collection and returning it in KittyDatabase
implementation via overloaded KittyDatabase.getStaticRegistryRegistry()
method.
Tip №2: Avoid multiply initialization of KittyDatabase
Each new instance of KittyDatabase
would execute a lot of operations on generating data model, registry, create and drop schema SQLite code etc. So, better approach would be place one initialized on demand instance of your KittyORM database into Application class and work only with this one instance.
Tip №3: Optimize your data model and statements
That’s simple. You have a lot of SELECT
queries on table with condition on some field? Index it. Build more efficient conditions for your statements. For example, you can follow this article for instructions related with optimizing your queries.
You want to insert a lot of entities? Use insert in transaction feature for DELETE
, UPDATE
and INSERT
statements. For example, for insertions use KittyMapper.insertInTransaction(List<M> models)
. This would cause execution your queries at one time instead of forcing SQLite run each of your statement separately, so in some cases using this tip would cause up to 20x faster execution of insertions.
Tip №4: Do not use WITHOUT ROWID
flag for your tables
KittyORM uses rowid
field for indication if this model is new or existing. If model corresponds to table that was created with WITHOUT ROWID
flag than KittyORM would have to run much more operations related with fetching synthetic or natural primary key value(s) in order to differ models.
Tip №5: Use predefined drop, create and migration scripts at production
While developing your data model step by step KittyORM would provide you good tool for generating scripts for creating schema, dropping schema and upgrading schema from version to version with usage of KittySimpleMigrationScriptGenerator Migrator
. However, you can slightly decrease initialization times of your KittyDatabase
implementation at production by using static scripts initialized in your KittyDatabase
implementation instance or by using those scripts stored at assets or file system. Just develop your data model, save generated by KittyORM schema scripts and use them instead of generating those scripts each time when you initialize new instance of your KittyDatabase
implementation.
Tip №6: Turn off logging at production
OK, you’re ready for production. Do not forget to turn off logging by setting isLoggingOn()
, isProductionOn()
and isKittyDexUtilLoggingEnabled()
flags of KITTY_DATABASE
annotation to false, true and false respectively. You may leave isLoggingOn()
flag on, however it is good idea to turn on isProductionOn()
flag because all of your queries would be logged to log stream that slows execution of statements and is a potential security vulnerability.
Tip №7: Run expensive operations not in UI thread
And last tip: run your database related operations in another thread, especially if there is chance that they can be expensive. Good practice is to run all database related operations in AsyncTask or use any other option to avoid execution of database code in UI thread. Why? Because SQLite is not as fast as light and KittyORM is another layer of code that needs resources for execution too. So using AsyncTask would be good idea to avoid UI lags and even ANR for long operations.