首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQLite C API中的静态和非静态准备状态

SQLite C API中的静态和非静态准备状态
EN

Stack Overflow用户
提问于 2014-03-03 21:21:24
回答 2查看 209关注 0票数 1

我正在用C和SQL开发一个终端应用程序来标记文件。文件/标记关系保存在SQLite 3数据库中。到目前为止,我一直在使用静态分配的准备语句,每次调用包装函数时都会对这些语句进行重置和绑定。最近,我正在用valgrind测试内存泄漏等问题,它抱怨很多,因为很明显,包装器中的静态sqlite3_stmt在程序终止时没有释放。这还会导致数据库无法正确关闭(因为未完成的语句)。

这样做的最初原因是性能。我在C接口简介中读到,重用准备好的语句对性能非常好。

在现有的准备语句上使用sqlite3_reset()而不是创建新的准备语句,可以避免不必要的对sqlite3_prepare()的调用。在许多SQL语句中,运行sqlite3_prepare()所需的时间等于或超过sqlite3_step()所需的时间。因此,避免对sqlite3_prepare()的调用可以显著提高性能。

下面是一些代码来展示我正在做的事情:

代码语言:javascript
复制
int tag_file(const char *file, const char *tag)
{
    static sqlite3_stmt *sql_prep = NULL;
    static const char *sql_str = "INSERT OR IGNORE INTO Tag VALUES (?, ?);";

    // Prepare if null, else reset
    prepare_or_reset(&sql_prep, sql_str);

    if (sqlite3_bind_text(sql_prep, 1, file, -1, SQLITE_STATIC) != SQLITE_OK ||
        sqlite3_bind_text(sql_prep, 2, tag, -1, SQLITE_STATIC) != SQLITE_OK)
        return ERROR;

    if (sqlite3_step(sql_prep) != SQLITE_DONE)
        return ERROR;

    return SUCCESS;
}

我尝试过的(它将满足valgrind,但完全忽略了重用准备语句的性能增益)是使sql_prep非静态,并在函数结束时调用sqlite3_finalize(sql_prep),但我认为这在性能上更糟糕。我可以只准备一次语句,而不会以一种优雅的方式泄漏内存?

我开始担心的另一件事是内存消耗。在未来,我计划为这个应用程序创建一个GUI,这将使所有这些在内存中保存得更久。性能的提高可能会更大,但从第一次调用退出开始,该语句就会出现在堆上。这是公平的空时贸易吗?

编辑:将所有“静态”准备好的语句保存在全局数组中(我可以释放atexit)是否很难看/很奇怪?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-04 09:24:03

  1. 在关闭数据库之前,必须最后完成所有语句。 如果在函数(如tag_file )之外不知道语句,则这是不可能的。您应该有一个全局语句列表,并让prepare_or_reset函数动态地将语句添加到该列表中。
  2. 准备好的语句很小;无法与GUI库分配的所有内容进行比较。很可能你甚至不会注意到他们的内存使用情况。 但是,如果您不经常执行准备语句,那么准备好的语句不会给速度带来很大的提高,因为准备时间是显而易见的。所以不管是哪种方式都不重要。☺
票数 2
EN

Stack Overflow用户

发布于 2014-03-03 23:20:16

你说的是两个问题。

  1. 第一个基本问题是如何管理您准备好的语句。 在这里,重新设计您的int tag_file(const char *file, const char *tag)函数似乎是合适的。 要么您将stmt保持在更高的级别,然后每次将它传递给函数。然后你就可以在程序的最后清理。 另一种方法是定义函数的语义,为其提供特殊的哨兵函数(可能只是(NULL, NULL)),从而使函数释放语句。
  2. 第二个问题是堆大小的问题。只要您没有数百或数千个准备好的stmt,我认为您可以一直使用它,因为它可能只需要几个字节。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22157714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档