Detecting forgotten SQLite transaction on Android using StrictMode? - android

Executing multiple SQL statements without putting them into one transaction is a severe bottleneck (see e.g. http://www.sqlite.org/faq.html#q19). I haven't thoroughly checked how SQLite is configured on Android, but anecdotally I perceived dramatical performance increase within my on app when using transactions in more places.
Is it possible to detect instances where one forgets to use transactions using StrictMode? If not, could that be considered for a future release of StrictMode? It might be somewhat tricky to detect, but two different strategies could be, 1) non-select statements outside transaction, or 2) multiple non-select statements outside transaction executed within a short period of time.

Yeah, that sounds like a good thing to catch. I could imagine an API like:
StrictMode.catchWritesOutsideTransactionsOn(SQLiteDatabase db);
We've been considering other SQLite hooks into StrictMode (mostly around selects missing indexes and such), but this is a good idea too!

Related

best speed trigger/statements/transaction

This is a general sqlite question and specifically as implemented on Android.
Which offers the best peformance if a deletion on one table would require deletions on another? This can be accomplished three ways that I see:
To use a trigger
DELETE statements
A Transaction wrapping the DELETEs
Hope I've phrased it correctly, I can muck around in sql but I might not express myself properly.
The only real way to answer a question like this is to build a test case, and try it.
There are many things that can affect the execution time of a statement, and when you start adding things like triggers and transactions, the number of variables grows even more.
Write a simple test case, specifically for your application, and see which works faster for you.
Also, be wary of premature optimization.

Android: Why not make every method Synchronized?

Is there any downside to making every one of your methods synchronized in Android?
Yes - it will end up taking out locks when you don't really want them. It won't give you thread safety for free - it'll just slow down your code and make it more likely that you'll run into deadlocks due to taking out too many locks.
You need to think about thread safety and synchronization explicitly. I usually make most classes not thread-safe, and try to limit the number of places where I think about threading.
The "make everything synchronized" approach is a common one in what I think of as the four stages of threading awareness for developers:
Complete ignorance: no synchronization, no awareness of the potential problems
Some awareness, but a belief that universal synchronization cures all ills
The painful stage of knowing where there are problems, and taking a lot of care over getting things right
The mythical stage of getting everything right naturally
Most experienced developers are in stage 3 as far as I can tell - with different levels of ease within it, of course. Using immutability, higher-level abstractions instead of the low-level primitives etc helps a lot - but ultimately you're likely to have to think a fair amount whenever you've got multiple threads which need to share state.

ORMLite poor performance on Android?

I'm developing an application for Android, and have tried to use ORMLite, but the performance seems to be really poor. Has anyone else experienced this?
Or am I doing something wrong?
EDIT
No I'm not doing any joins, and all queries are made with indexed keys as parameters. But the data set is resonably big, and there is quite many comparisions.
Haven't tried to do with pure SQLite...
I guess the best answer is that the performance of ORMLite is highly dependent on how you use it. If you could post some of the code samples as well as some of the performance numbers, we may be able to help more specifically.
If you are making a number of database operations at one time, you should consider using the Dao.callBatchTasks() method. Under Android, it starts a database transaction, calls the passed in Callable and after it returns, it commits the transaction. This is significantly faster if you are, for example, inserting a number of rows into the table.
See also: Why is the DAO method so slow in ORMLite?
EDIT
If your queries are taking a while then most likely the time is being spent in SQLite. You could try reducing some of the dataset or tuning the number of comparisons to see if things run faster so you can definitively determine that SQLite (and more likely just IO) is the culprit.

producer consumer

i have an application which has a part where some variables are written and read at very high frequency.
Is there any need of a semaphores or locks(Data consistency is not a concern in this case).Is there any chance of application terminating or crashing.I dont want to get into threads,semaphores and stuff as it is a trivial part of application.
There is not nearly enough information in your question to give you an accurate answer, but in general - if you have multiple threads, and one produces data, one consumes it, then yes, you will need synchronization.
You could use a BlockingQueue, or just a simple synchronized object, whatever is appropriate in your case... but you will need some synchronization, or else you risk random hard-to-reproduce crashes.
This is even more important when dealing with multi-core systems, which are becoming popular now.

Content providers: wrap with a static facade?

I am going through a bit of a design dilemma, I have been targeting Android 2.3.3 and have a custom implementation of a ContentProvider. I then have a class of static methods to abstract the Content provider - providing me with objects representing each entity (row) based upon my query. For a while I was very comfortable with working like this, until I started wanting to use the whole collection in a number of places, for performing "hit tests" and drawing to the screen. I then had the headache of keeping my object representations up to date, and at this point have decided I need to step back and reconsider where to take this.
As I say, I am presently using 2.3.3, and realise that in 3.0 CursorLoader overcomes a lot of the problems I have encountered. I still need to support smart phones though, so unless there will be a backport I cannot do this.
As an interim solution I started to register notifyChange listeners so that I can rebuild a collection with my original query, but this strikes me as very CPU intensive and potentially slow. I haven't yet decided whether I should roll back from using my static facade and instead use the now obsolete managedQuery call from Activity.
I therefore have two questions:
1) Is there a preferrable way to avoid the issues with working against a collection based around a contentProvider?
2) Have you any advice on working with raw cursors in an activity? Should I be making objects out of them or working with the cursor as-is? I certainly feel they should be in an AsynTask while performing the query, but after that can I use them anywhere?
Ok, well I came to a decision and it works reliably.
1) Is there a preferable way to avoid
the issues with working against a
collection based around a
ContentProvider?
I have decided that the approach I took was correct; In my situation it is preferred to make a cache rather than maintain a cursor (managed or not) to the ContentProvider; this allows me to reuse methods and reduce the amount of code that requires testing. NotifyChange listeners are important until working on 3.0+ and that means I should guarantee the NotifyChange is called - another argument for centralising all of this code, so that it indeed triggers the changes when expected.
2) Have you any advice on working with
raw cursors in an activity? Should I
be making objects out of them or
working with the cursor as-is? I
certainly feel they should be in an
AsyncTask while performing the query,
but after that can I use them
anywhere?
In my use case I have decided it is a matter of thinking about what it is I am planning to create - avoid unnecessary work, with respect to returning unnecessary rows & fields and potentially creating unnecessary objects. If I am looking to create a map of entry names and entry IDs then I shouldn't be getting all of the other fields too. Abstracting from the collection is good but it must be lightweight and take in to account how the data is used - whether it is a one-off or may be used repeatedly. It is important that it is written for performance rather than completeness.

Categories

Resources