【问题标题】:ORMLite's createOrUpdate seems slow - what is normal speed?ORMLite 的 createOrUpdate 似乎很慢 - 什么是正常速度?
【发布时间】:2012-07-30 11:31:55
【问题描述】:

在我的应用程序中调用 ORMLite RuntimeExceptionDaocreateOrUpdate(...) 方法非常慢。

我有一个非常简单的对象 (Item),它有 2 个整数(一个是 generatedId)、一个 String 和一个 double。我用下面的代码测试了(大致)更新数据库中的对象(100 次)所需的时间。日志语句记录:

更新 1 行 100 次的时间:3069

为什么在一个只有 1 行的表中更新一个对象 100 次需要 3 秒。这是正常的 ORMLite 速度吗?如果不是,可能是什么问题?

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 个新行,那么速度会更慢。

注意:我已经在使用ormlite_config.txt。它记录了"Loaded configuration for class ...Item",所以这不是问题。

谢谢。

【问题讨论】:

    标签: android performance ormlite


    【解决方案1】:

    不幸的是,这可能是“预期”的速度。确保您使用的是 ORMLite 4.39 或更高版本。 createOrUpdate(...) 正在使用一种更昂贵的方法来预先测试数据库中对象的存在。但我怀疑这将是最小的速度提升。

    如果我创建 100 个新行,那么速度会更慢。

    默认情况下,Sqlite 处于自动提交模式。要尝试的一件事是使用 ORMLite Dao.callBatchTasks(...) 方法包装您的插入(或您的 createOrUpdates)。

    BulkInsertsTest android unit test 中,以下doInserts(...) 方法插入1000 个项目。当我调用它时:

    doInserts(dao);
    

    在我的模拟器中需要 7.3 秒。如果我使用 callBatchTasks(...) 方法调用,该方法在 Android Sqlite 中围绕调用包装事务:

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

    需要 1.6 秒。使用dao.setSavePoint(...) 方法可以获得相同的性能。这会启动一个事务,但不如 callBachTasks(...) 方法好,因为您必须确保关闭自己的事务:

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

    这也需要大约 1.7 秒。

    【讨论】:

    • 谢谢! callBatchTasks 方法使它更快,它使速度还可以,即使不是完美的。当用户滚动时(我猜),300 毫秒会导致一个小问题。唯一的解决方案是将其移动到单独的线程中?
    • 移动到一个单独的线程,如果你确实可以在后台做,肯定不会阻塞 UI。你可以试试@Frank。
    • 在旁注中,documentationcallBatchTasks 的示例中显示无效(旧?)语法(第一个参数是 ConnectionSource)。
    猜你喜欢
    • 2014-11-26
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 2012-05-10
    相关资源
    最近更新 更多