marcoarment / FCModel

An alternative to Core Data for people who like having direct SQL access.
MIT License
1.65k stars 173 forks source link

[FMResultSet next] takes too long on app startup #78

Closed irvingruan closed 10 years ago

irvingruan commented 10 years ago

I'm opening the connection to the database like the sample code shows and while running it through Instruments, I'm getting around ~3.7s for [FMResultSet next] under Time Profiler.

In my DB, I have 20 items, with negligible BLOB data and several attributes — nothing too fancy nor complicated.

Hi

My speculation is that I'm iterating through an NSArray that is the returned value of calling my model's -allInstances but it seems that operation should be performant.

I'm not sure if there is a spinlock occurring in [FMResultSet next] but I'm curious to hear if anyone has encountered this before.

marcoarment commented 10 years ago

That's definitely not normal.

FMDB has a backoff-retry system when SQLite is busy from another thread. In the worst cases, it can delay by seconds. Are you doing concurrent database operations that might be causing the database to be busy?

irvingruan commented 10 years ago

Interesting. I ran some more tests and it seems that iterating through the rows — in this case, instances — of my model class and accessing their individual properties would invoke -next multiple times. This isn't surprising, but I didn't expect accessing ~8 properties per instance for a total of 20 instances would take that much time.

I turned it down to only reading 1 property per instance and that dramatically slowed down [FMResultSet next] running time. FCModel is built on a single-task queue, right? "Concurrent" database operations, it seems, would just get offloaded to that one serial queue.

marcoarment commented 10 years ago

In pure FCModel usage, yes, SQLITE_BUSY should never happen. But sometimes people share the database with other code and bypass the queue. (For the record, please don't do that.)

I'm curious why seemingly normal usage is so slow for you, though. When you say your model instances' property accesses are invoking -next, that's not built-in FCModel behavior — FCModel doesn't implement any property getters/setters, doesn't interfere with their operation, and doesn't observe changes.

Are these custom getters you wrote that are querying the database?

irvingruan commented 10 years ago

No, these are not custom getters — just Obj-C properties.

Upon further investigation, the multiple property accessing was a red herring. Your original hypothesis was indeed correct: concurrent database operations was causing the DB to be busy. I had various timers set up to do DB reads, which I re-architected to be more efficient and thread-safe.

Thanks for the help, Marco. I originally didn't suspect that it was FMDB causing it but I wanted to double check to see what possible permutations would lead to FMResultSet taking longer than usual. You can close this.

marcoarment commented 10 years ago

Whew, glad it's not my bug. Thanks.