Ho fatto alcuni esperimenti per misurare le prestazioni in sqlite su Android. Sono rimasto un po 'deluso dai risultati. Quello che ho fatto è stato inserire 10.000 query al tavolo e ci sono voluti 130-140 secondima con queste condizioni;Prestazioni Sqlite Android
1. galassia s3 a risparmio energetico modalità
2. dati inseriti (o classe) ha 3 corde e un galleggiante (reali per SQLite)
3. Inserisci evento è in corso in asynctask.
4. In AsyncTask, sto mostrando un progresso dialogo con testo timer passato in esso (System.currentTimeMillis - secondi ecc blala)
class AddStudentsTask extends AsyncTask<Void,Integer,Void>
{
ProgressDialog prgDialog;
int max = 10000;
Student s;
long seconds = System.currentTimeMillis();
@Override
protected void onPreExecute() {
super.onPreExecute();
prgDialog = new ProgressDialog(MainActivity.this);
prgDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
prgDialog.setMessage(seconds+"");
prgDialog.setMax(max);
prgDialog.setCancelable(false);
prgDialog.show();
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate();
prgDialog.setProgress(values[0]);
sList.add(s);
String s = (System.currentTimeMillis()-seconds)/100+"";
if(s.length()>2)
s = s.substring(0,s.length()-1) + "." + s.charAt(s.length()-1);
else if(s.length() == 2)
s = s.charAt(0) + "." + s.charAt(1);
prgDialog.setMessage(s + " seconds passed.");
}
@Override
protected Void doInBackground(Void... voids) {
for(int a = 0;a< max; a++)
{
Random r = new Random();
s = new Student();
s.setGpa(r.nextFloat()*4);
s.setLastName("asdasd");
s.setFirstName("Oh My Fuckig God");
s.setAddress("1sadasd");
s.setId(sda.insert(s));
publishProgress(a);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
prgDialog.dismiss();
sa.notifyDataSetChanged();
}
}
5. Sto usando contentValues con metodo insertOrThrow in classe helperdb. Questo è un codice SLOW VECCHIO
public long insert(Student s)
{
SQLiteDatabase db = sh.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(StudentHelper.FIRSTNAME,s.getFirstName());
cv.put(StudentHelper.LASTNAME,s.getLastName());
cv.put(StudentHelper.ADDRESS,s.getAddress());
cv.put(StudentHelper.GPA,s.getGpa());
s.setId(db.insertOrThrow(StudentHelper.TABLE_NAME, null, cv));
return s.getId();
}
6. Questo compito viene fatto in modo onCreate di attività.
Quindi cosa sto facendo di sbagliato qui o mi aspetto troppo da esso? Questi risultati sono ok o cattivi?
Cosa posso fare per migliorare il mio codice?
EDIT
Così ho cambiato il mio codice Inserisci per questo ed è ridotto a 4,5 secondi !!!
public ArrayList<Long> insertMany(ArrayList<Student> stus)
{
ArrayList<Long> ids = new ArrayList();
String sql = "INSERT INTO "+StudentHelper.TABLE_NAME+"" +
"("+StudentHelper.FIRSTNAME+","+StudentHelper.LASTNAME+"," +
" "+StudentHelper.GPA+") values(?,?,?)";
SQLiteDatabase db = sh.getWritableDatabase();
db.beginTransaction();
for(Student s:stus) {
SQLiteStatement stmt = db.compileStatement(sql);
stmt.bindString(1, s.getFirstName());
stmt.bindString(2, s.getLastName());
stmt.bindDouble(3, s.getGpa());
s.setId(stmt.executeInsert());
ids.add(s.getId());
stmt.clearBindings();
}
db.setTransactionSuccessful();
db.endTransaction();
return ids;
}
Non vedo 'endTransaction' o' setTransactionSuccessful' se appena aggiunto 'beginTransaction' nel vostro' metodo insert' allora ti sei perso il punto. –
@ M-WaJeEh Hai ragione. Ho modificato il mio post. Grazie per le critiche costruttive !! –
No, ancora sbagliato. Devi fare 'beginTransaction' e poi 10.000 inserzioni e poi' setTransactionSuccessful' e quindi 'endTransaction'. Modifica il tuo 'AddStudentsTask' affinché funzioni. –