views:

45

answers:

0

I made a javascript class that let me use gears or html5 (if available) storage to store an stringified json object. the code is ment to be use on Android 1.5 and 2.0. When I save many objects into gears, it's very slow even on a PC (google chrome / gears). The CPU doesn't go high but the page gets unresponsive for 45 sec. On a cellphone it's even worse. I removed the makeJsonString(oContent) but it's the same. The html5 part of the code (in IE8) works fast (2 sec to insert 300 elems).

On the phone, I only do 1 insert at the time.

In the constructor:

this.db = google.gears.factory.create('beta.database');
this.db.open("foobar");
this.db.execute('CREATE TABLE IF NOT EXISTS ' + this.sDatabase + ' (AUTO_ID INTEGER PRIMARY KEY AUTOINCREMENT, CONTENT_JSON TEXT);');

The saving part:

var sContent = makeJsonString(oContent);
this.db.execute("INSERT INTO " + this.sDatabase + " (CONTENT_JSON) VALUES (?)", [sContent]);

The testing code:

var oContent = {};
oContent.field = "test'os";
for (var i = 1; i < 300; i++)
 db.saveContent(oContent);

makeJsonString use json2.js or the native function.

EDIT

Google Chrome CPU profiling: alt text

EDIT 2

from: http://www.sqlite.org/faq.html#q19

Actually, SQLite will easily do 50,000 or more INSERT statements per second on an average desktop computer. But it will only do a few dozen transactions per second. Transaction speed is limited by the rotational speed of your disk drive. A transaction normally requires two complete rotations of the disk platter, which on a 7200RPM disk drive limits you to about 60 transactions per second. Transaction speed is limited by disk drive speed because (by default) SQLite actually waits until the data really is safely stored on the disk surface before the transaction is complete. That way, if you suddenly lose power or if your OS crashes, your data is still safe. For details, read about atomic commit in SQLite..

By default, each INSERT statement is its own transaction. But if you surround multiple INSERT statements with BEGIN...COMMIT then all the inserts are grouped into a single transaction. The time needed to commit the transaction is amortized over all the enclosed insert statements and so the time per insert statement is greatly reduced.

Another option is to run PRAGMA synchronous=OFF. This command will cause SQLite to not wait on data to reach the disk surface, which will make write operations appear to be much faster. But if you lose power in the middle of a transaction, your database file might go corrupt.

adding a transaction (BEGIN, COMMIT) boosted the performance for 300 insert from 45 sec to ~1 sec. Still need to test it on the phone.

EDIT 3

still slow on the phone :(