Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the fastest way to parse a JSON string into an SQLite table?

I'm writing an Android application which will occasionally need to download a json string of around 1MB and containing around 1000 elements, and parse each of these into an SQLite database, which I use to populate a ListActivity.

Even though the downloading and parsing isn't something that needs to be done on every interaction with the app (only on first run or when the user chooses to refresh the data), I'm still concerned that the parsing part is taking too long, at around two to three minutes - it seems like an eternity in phone app terms!

I'm currently using Gson to parse each json object into a custom object that I've defined, and then using an SQLiteOpenHelper to enter it into the database.

My question is - is there a faster way of implementing this? Would it be noticeably faster to interact with the json directly, without using Gson? Or am I doing something stupid in the code below that's slowing things down?

Here's the method I'm using in my AsyncTask to parse the json to SQLite:

protected Boolean doInBackground(Integer... bType) {

    InputStream source = getJsonInputStream(bTypeString);

    VegDataHandler db = new VegDataHandler(mainActivity, bTypeString);
    Gson gson = new Gson();
    Reader reader = new InputStreamReader(source);

    JsonParser jParser = new JsonParser();
    JsonArray jArray = jParser.parse(reader).getAsJsonArray();

    aLength = jArray.size();
    mCurrProgress = 1;
    publishProgress(mCurrProgress, 0, aLength);

    /* Each array element is of the form { company: {...} } */
    int i = 0;
    mCurrProgress = 2;
    for (JsonElement obj : jArray) {
        Company c = gson.fromJson(obj.getAsJsonObject().getAsJsonObject("company"), Company.class);
        db.addCompany(c);
        i++;
        publishProgress(mCurrProgress, i);
    }
}

This is the addCompany method from my VegDataHandler class, which extends SQLiteOpenHelper:

public void addCompany(Company c) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(KEY_ID, c.getCompanyId());
    values.put(KEY_NAME, c.getCompanyName());
    values.put(KEY_RYG, c.getCompanyRedYellowGreen());
    values.put(KEY_COUNTRY, c.getCompanyCountry());
    values.put(KEY_URL, c.getCompanyUrl());
    values.put(KEY_NOTES, c.getCompanyNotes());
    values.put(KEY_EMAIL, c.getCompanyEmail());
    db.insertWithOnConflict(TABLE_COMPANY, null, values, SQLiteDatabase.CONFLICT_REPLACE);
    db.close();
}

This is the class that holds each json element before adding to the SQLite (I've omitted the getters and setters for brevity).

public class Company {

    public Company() {
    }

    @SerializedName("id")
    public int companyId;

    @SerializedName("company_name")
    public String companyName;

    @SerializedName("red_yellow_green")
    public String companyRedYellowGreen;

    @SerializedName("country")
    public String companyCountry;

    @SerializedName("url")
    public String companyUrl;

    @SerializedName("notes")
    public String companyNotes;

    @SerializedName("email")
    public String companyEmail;

}

Thanks in advance for any replies.

like image 975
simick Avatar asked May 31 '12 13:05

simick


People also ask

Is JSON parse fast?

parse is a slow way to create a copy of an object. But can it actually improve the performance of our code?

How do I insert a JSON file into SQLite?

The SQLite json_insert() function allows us to insert a new value into a JSON document. We pass the original JSON as the first argument when we call the function, followed by a path that specifies where to insert the new value, followed by the value to insert. We can also insert multiple key/value pairs if required.

Can SQLite handle JSON?

SQLite stores JSON as ordinary text. Backwards compatibility constraints mean that SQLite is only able to store values that are NULL, integers, floating-point numbers, text, and BLOBs. It is not possible to add a sixth "JSON" type. SQLite does not (currently) support a binary encoding of JSON.


1 Answers

First you need to determine the portion(s) of the process that are eating up the most time. From your comment above it sounds like the JSON parsing is the culprit.

If JSON parsing is the issue:
Research and consider a faster JSON parser. Perhaps something like json-smart.

If SQLite/DB bulk inserts are the issue:
See my answer here

General tips:

  • Recycle objects as much as possible (keep new to a minimum)
  • Always use transactions in DB bulk inserts at the very least
  • Don't open/close the database. Do this once at the start/finish of your processing
  • Use pre-compiled statements!
like image 179
NuSkooler Avatar answered Oct 07 '22 16:10

NuSkooler