优化SQLite很棘手.C应用程序的批量插入性能可以从每秒85次插入到每秒超过96,000次插入!
背景:我们使用SQLite作为桌面应用程序的一部分.我们有大量的配置数据存储在XML文件中,这些数据被解析并加载到SQLite数据库中,以便在初始化应用程序时进行进一步处理.SQLite非常适合这种情况,因为它速度快,不需要专门配置,数据库作为单个文件存储在磁盘上.
理由: 最初我对我所看到的表现感到失望.事实证明,SQLite的性能可能会有很大差异(对于批量插入和选择),具体取决于数据库的配置方式以及如何使用API.弄清楚所有选项和技术是什么并不是一件小事,所以我认为创建这个社区wiki条目以与Stack Overflow读者分享结果是谨慎的,以便为其他人节省相同调查的麻烦.
实验:我不是简单地谈论一般意义上的性能提示(即"使用事务!"),而是认为最好编写一些C代码并实际测量各种选项的影响.我们将从一些简单的数据开始:
我们来写一些代码吧!
代码:一个简单的C程序,它逐行读取文本文件,将字符串拆分为值,然后将数据插入SQLite数据库.在代码的这个"基线"版本中,创建了数据库,但我们实际上不会插入数据:
/*************************************************************
Baseline code to experiment with SQLite performance.
Input data is a 28 MB TAB-delimited text file of the
complete Toronto Transit System schedule/route info
from http://www.toronto.ca/open/datasets/ttc-routes/
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "sqlite3.h"
#define INPUTDATA "C:\\TTC_schedule_scheduleitem_10-27-2009.txt"
#define DATABASE "c:\\TTC_schedule_scheduleitem_10-27-2009.sqlite"
#define …
Run Code Online (Sandbox Code Playgroud) 在这个问题,有人建议意见,我应该不会投的结果malloc
,即
int *sieve = malloc(sizeof(int) * length);
Run Code Online (Sandbox Code Playgroud)
而不是:
int *sieve = (int *) malloc(sizeof(int) * length);
Run Code Online (Sandbox Code Playgroud)
为什么会这样呢?
在C和C++编程语言中,使用尖括号和在include
语句中使用引号有什么区别,如下所示?
#include <filename>
#include "filename"
假设a1
,b1
,c1
,并d1
指向堆内存和我的数字代码具有下列核心循环.
const int n = 100000;
for (int j = 0; j < n; j++) {
a1[j] += b1[j];
c1[j] += d1[j];
}
Run Code Online (Sandbox Code Playgroud)
该循环通过另一个外for
循环执行10,000次.为了加快速度,我将代码更改为:
for (int j = 0; j < n; j++) {
a1[j] += b1[j];
}
for (int j = 0; j < n; j++) {
c1[j] += d1[j];
}
Run Code Online (Sandbox Code Playgroud)
在MS Visual C++ 10.0上进行了全面优化编译,在Intel Core 2 Duo(x64)上为32位启用了SSE2,第一个示例需要5.5秒,双循环示例仅需1.9秒.我的问题是:(请参考我在底部的改写问题)
PS:我不确定,如果这有帮助:
第一个循环的反汇编基本上是这样的(这个块在整个程序中重复大约五次):
movsd xmm0,mmword ptr [edx+18h]
addsd …
Run Code Online (Sandbox Code Playgroud) 我看到一行C看起来像这样:
!ErrorHasOccured() ??!??! HandleError();
Run Code Online (Sandbox Code Playgroud)
它编译正确,似乎运行正常.看起来它正在检查是否发生了错误,如果有错误,它会处理它.但我不确定它在做什么或它是如何做的.看起来程序员正试图表达他们对错误的看法.
我从来没有??!??!
在任何编程语言中看过以前,我无法在任何地方找到它的文档.(Google对搜索字词没有帮助??!??!
).它做了什么以及代码示例如何工作?
我在/usr/include/linux/kernel.h中碰到了这个奇怪的宏代码:
/* Force a compilation error if condition is true, but also produce a
result (of value 0 and type size_t), so the expression can be used
e.g. in a structure initializer (or where-ever else comma expressions
aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
Run Code Online (Sandbox Code Playgroud)
怎么:-!!
办?
正如Joel在Stack Overflow播客#34中用C编程语言(又名:K&R)所指出的那样,在C中提到了数组的这种属性:a[5] == 5[a]
乔尔说,这是因为指针运算,但我仍然不明白.为什么a[5] == 5[a]
?
c ×10
c++ ×5
performance ×2
arrays ×1
casting ×1
embedded ×1
extern-c ×1
gcc ×1
header-files ×1
include ×1
linkage ×1
linux ×1
linux-kernel ×1
macros ×1
malloc ×1
operators ×1
optimization ×1
pointers ×1
sqlite ×1
trigraphs ×1