2012-08-01 9 views
8

Uygulamamdaki ORMLite RuntimeExceptionDao ürününün createOrUpdate(...) yöntemini çağırmak çok yavaş.ORMLite'nin createOrUpdate'i yavaş görünüyor - normal hız nedir?

bir 2 ints ile çok basit bir nesne (Item) (bir generatedId olduğunu), bir String ve double. Aşağıdaki kodu kullanarak veritabanında (100 kez) nesneyi güncellemek için gereken süreyi (kabaca) test ediyorum. Günlük deyimi günlükleri:

zaman 1 sıra 100 kez güncellemek için: 3069

Neden sadece 1 satır içeren bir tabloda, Bir nesneyi 100 kez güncellemek için 3 saniye sürer. Bu normal ORMLite hızı mı? Değilse, sorun ne olabilir?

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)); 

100 yeni satır oluşturursam, hız daha da yavaş olur.

Not: Zaten ormlite_config.txt kullanıyorum. Bu "Loaded configuration for class ...Item" kaydeder, bu sorun değil.

Teşekkürler.

cevap

23

Bu, ne yazık ki "beklenen" hız olabilir. ORMLite 4.39 veya daha yeni bir sürüm kullandığınızdan emin olun. createOrUpdate(...), daha önce veritabanındaki nesnenin varlığını test etmek için daha pahalı bir yöntem kullanıyordu. Ama bunun asgari bir hız artışı olacağından şüpheleniyorum.

100 yeni satır oluşturursam, hız daha da yavaş olur.

Varsayılan olarak Sqlite otomatik işlem modunda. Denenecek bir şey, eklerinizi (veya createOrUpdate s) ORMLiteDao.callBatchTasks(...) yöntemini kullanarak sarmaktır.

BulkInsertsTest android unit test'da, aşağıdaki doInserts(...) yöntemi 1000 öğe ekler. Sadece aradığımda: Emülatörümde 7.3 saniye sürüyor. Ben Android SQLite içinde çağrı etrafında işlemleri sarar callBatchTasks(...) yöntemiyle çağırırsanız:

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

O 1.6 saniye sürer. Aynı performans dao.setSavePoint(...) yöntemi kullanılarak da elde edilebilir. Bu bir hareket başlatır ama emin kendi işlem kapatmak yapmak zorunda çünkü callBachTasks(...) yöntemle kadar iyi değildir:

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); 
} 

Bu aynı zamanda 1.7 saniye ~ sürer.

+0

Teşekkürler! CallBatchTasks yöntemi onu çok daha hızlı hale getirir, mükemmel değilse bile hızı düzeltir. Kullanıcı kaydırma yaparken 300 ms küçük bir hickup ile sonuçlanacaktır (tahmin ediyorum). Bunun tek çözümü, onu ayrı bir iş parçacığına mı taşıyor? – Frank

+0

Ayrı bir iş parçacığına geçmek, arka planda gerçekten yapabilirseniz, UI'yi kesinlikle engellemez. Bunu deneyebilirsin @Frank. – Gray

+1

Bunun için bir örnek olarak, [document] (http://ormlite.com/javadoc/ormlite-core/doc-files/ormlite_5.html#index-callBatchTasks), örnekte geçersiz (eski?) Bir sözdizimi gösterir. 'callBatchTasks' (ilk parametre ConnectionSource'tur). – Czechnology