2012-08-01 7 views
8

Llamar al método RuntimeExceptionDao de ORMLite createOrUpdate(...) en mi aplicación es muy lento.El createOrUpdate de ORMLite parece lento, ¿cuál es la velocidad normal?

Tengo un objeto muy simple (Item) con un 2 ints (una es la generatedId), un String y una double. Pruebo el tiempo que toma (aproximadamente) actualizar el objeto en la base de datos (100 veces) con el siguiente código. Los registros de los estados de registro:

tiempo para actualizar la fila 1 100 veces: 3069

¿Por qué tarda 3 segundos para actualizar un objeto 100 veces, en una tabla con sólo 1 fila. ¿Es esta la velocidad ORMLite normal? Si no, ¿cuál podría ser el problema?

RuntimeExceptionDao<Item, Integer> dao = 
    DatabaseManager.getInstance().getHelper().getReadingStateDao(); 
Item item = new Item(); 
long start = System.currentTimeMillis(); 
for (int i = 0; i < 100; i++) { 
    item.setViewMode(i); 
    dao.createOrUpdate(item); 
} 
long update = System.currentTimeMillis(); 
Log.v(TAG, "time to update 1 row 100 times: " + (update - start)); 

Si creo 100 filas nuevas, la velocidad es incluso más lenta.

Nota: Ya estoy usando ormlite_config.txt. Registra "Loaded configuration for class ...Item", así que este no es el problema.

Gracias.

Respuesta

23

Desafortunadamente, esta puede ser la velocidad "esperada". Asegúrese de estar utilizando la versión 4.39 o posterior de ORMLite. createOrUpdate(...) estaba usando un método más costoso para probar la existencia del objeto en la base de datos de antemano. Pero sospecho que esto va a ser una mejora de velocidad mínima.

Si creo 100 filas nuevas, la velocidad es incluso más lenta.

De forma predeterminada, Sqlite está en modo autocompromiso. Una cosa para intentar es envolver sus inserciones (o su createOrUpdate s) utilizando el método ORMLite .

En BulkInsertsTest android unit test, el siguiente método doInserts(...) inserta 1000 elementos. Cuando lo llamo:

doInserts(dao); 

Demora 7.3 segundos en mi emulador. Si llamo utilizando el método callBatchTasks(...) que envuelve a las transacciones en torno a la llamada en Android SQLite:

dao.callBatchTasks(new Callable<Void>() { 
    public Void call() throws Exception { 
     doInserts(dao); 
     return null; 
    } 
}); 

Se tarda 1,6 segundos. Se puede obtener el mismo rendimiento utilizando el método dao.setSavePoint(...). Esto inicia una transacción, pero no es tan bueno como el método callBachTasks(...) porque usted tiene que asegurarse de que cierre su propia transacción:

DatabaseConnection conn = dao.startThreadConnection(); 
Savepoint savePoint = null; 
try { 
    savePoint = conn.setSavePoint(null); 
    doInserts(dao); 
} finally { 
    // commit at the end 
    conn.commit(savePoint); 
    dao.endThreadConnection(conn); 
} 

Esto también lleva a ~ 1,7 segundos.

+0

Gracias! El método callBatchTasks lo hace mucho más rápido, hace que la velocidad sea correcta, sino perfecta. 300 ms dará lugar a un pequeño aumento cuando el usuario está desplazándose (supongo). La única solución para eso es moverlo a un hilo separado? – Frank

+0

Al pasar a un hilo separado, si puede hacerlo en segundo plano, no bloqueará la interfaz de usuario. Puede intentarlo @Frank. – Gray

+1

En una nota al respecto, la [documentación] (http://ormlite.com/javadoc/ormlite-core/doc-files/ormlite_5.html#index-callBatchTasks) muestra una sintaxis inválida (¿antigua?) En el ejemplo de 'callBatchTasks' (primer parámetro es ConnectionSource). – Czechnology

Cuestiones relacionadas