it seems that this mail list will filter my code. I re-send it now.
It?s written by Objective-C and C, but it?s quite simple to understand.
void sqliteLog(void* userInfo, int retCode, const char* text)
{
if (retCode != SQLITE_OK) {
NSLog(@"SQLITE FAILED errCode=%d, errMsg=%s", retCode, text);
}
}
@implementation TestCase {
NSString* _path;
NSUInteger _threadCount;
}
- (id)init
{
if (self = [super init]) {
NSString* document =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,
YES)[0];
_path = [document stringByAppendingPathComponent:@"test.sqlite"];
_threadCount = 4;
}
return self;
}
- (void)clear
{
//remove existing DB file
NSFileManager* fm = [NSFileManager defaultManager];
NSArray* paths = @[_path, [_path stringByAppendingString:@"-shm"], [_path
stringByAppendingString:@"-wal"], [_path stringByAppendingString:@"-journal"]];
for (NSString* path in paths) {
if ([fm fileExistsAtPath:path]) {
NSLog(@"file exists %@", path);
NSError* error;
if (![fm removeItemAtPath:path error:error]) {
NSLog(@"remove error %@", error);
exit(0);
}
}
}
}
- (void)prepare
{
[self clear];
sqlite3_config(SQLITE_CONFIG_LOG, sqliteLog, NULL);
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3* handle;
sqlite3_open(_path.UTF8String, handle);
//pragma
sqlite3_exec(handle, "PRAGMA LOCKING_MODE=NORMAL;", NULL, NULL, NULL);
sqlite3_exec(handle, "PRAGMA JOURNAL_MODE=WAL;", NULL, NULL, NULL);
sqlite3_exec(handle, "PRAGMA SYNCHRONOUS=FULL;", NULL, NULL, NULL);
//create table
sqlite3_exec(handle, "CREATE TABLE testtable (id INT PRIMARY KEY);", NULL,
NULL, NULL);
//pre insert
sqlite3_exec(handle, "BEGIN", NULL, NULL, NULL);
sqlite3_stmt* stmt;
sqlite3_prepare_v2(handle, "INSERT INTO testtable (id) VALUES (?);", -1,
stmt, NULL);
for (int i = 0; i 1000000; i++) {
sqlite3_bind_int(stmt, 1, i);
sqlite3_step(stmt);
sqlite3_reset(stmt);
}
sqlite3_exec(handle, "COMMIT", NULL, NULL, NULL);
sqlite3_finalize(stmt);
sqlite3_close(handle);
}
- (void)test
{
[self prepare];
NSRecursiveLock* lock = [[NSRecursiveLock alloc] init];
__block NSUInteger threadWait = _threadCount;
for (int i = 0; i _threadCount; i++) {
NSString* threadname = [NSString stringWithFormat:@"test_thread_%d", i];
dispatch_async(dispatch_queue_create(threadname.UTF8String,
DISPATCH_QUEUE_CONCURRENT), ^{
NSString* start = [NSString stringWithFormat:@"%@ start", [NSThread
currentThread]];
NSString* end = [NSString stringWithFormat:@"%@ end", [NSThread
currentThread]];
sqlite3* handle;
sqlite3_open(_path.UTF8String, handle);
//wait for all thread
[lock lock];
threadWait--;
[lock unlock];
while (threadWait);
//begin
[Ticker tickWithInfo:start];
sqlite3_exec(handle, "SELECT * FROM testtable", NULL, NULL, NULL);
[Ticker stopWithInfo:end];
sqlite3_close(handle);
});
}
}
@end
????
???:Richard Hippdrh at sqlite.org
???:SQLite mailing listsqlite-users at mailinglists.sqlite.org
????:2015?11?1?(??)?03:45
??:Re: [sqlite] Why SQLite take lower performance in multi-threadSELECTing?
On 10/30/15, sanhua.zh sanhua.zh at foxmail.com wrote: Hi, all I use SQLite
in iOS. I found that SQLite will take lower performancein multi-thread
SELECTing. Here is my test result, It costs 0.11s to select 100,0000
elements,in 1-thread SELECTing: But the sameIn 4-thread SELECTing, it costs
0.2s avg. This test run on iPhone 6s. You can see that 4-thread is take
almost twice slower than 1-thread. I know multi-thread might costs the system
resource, but this result is much slower than what I excepted. Is there some
race condition in SQLite or I write the wrong code ? You *might* be doing
something wrong. It is hard to say without seeing your code. But the 2x
slowdown might be entirely due to thread contention and mutexing. Remember that
the flash memory filesystem on iOS has finite bandwidth, and all the threads in
the world will not increase that bandwidth. The extra threads just cause extra
overhead which ends up slowing everything down. -- D. Richard Hipp drh at
sqlite.org _______________________________________________ sqlite-users mailing
list sqlite-users at mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users