2015-09-25 115 views
0

我写我的代码到select在3个线程中并发单线程一个连接;我发现它比1个线程慢;多线程读取会导致性能下降吗?

这里是我的测试数据:
这是一个表(索引uint32)与100000项;

当我在3个一线选择 10万项目(所有项目):

0: 1443185531.782627, info: <NSThread: 0x13f99ac40>{number = 4, name = (null)} read ready 
1: 1443185531.782634, cost 0.000007, info: <NSThread: 0x13f99ac40>{number = 4, name = (null)} read start 
2: 1443185533.365550, cost 1.582916, info: <NSThread: 0x13f99ac40>{number = 4, name = (null)} read end 

0: 1443185531.772624, info: <NSThread: 0x13f871e60>{number = 2, name = (null)} read ready 
1: 1443185531.782659, cost 0.010035, info: <NSThread: 0x13f871e60>{number = 2, name = (null)} read start 
2: 1443185533.372972, cost 1.590313, info: <NSThread: 0x13f871e60>{number = 2, name = (null)} read end 

0: 1443185531.773191, info: <NSThread: 0x13f99a6a0>{number = 3, name = (null)} read ready 
1: 1443185531.782636, cost 0.009445, info: <NSThread: 0x13f99a6a0>{number = 3, name = (null)} read start 
2: 1443185533.393716, cost 1.611080, info: <NSThread: 0x13f99a6a0>{number = 3, name = (null)} read end 

你可以看到它的成本1.5秒的平均水平。
但是,当我更改为选择 10万项目(所有项目)在1线:

0: 1443185738.427020, info: <NSThread: 0x14d970990>{number = 2, name = (null)} read ready 
1: 1443185738.427106, cost 0.000086, info: <NSThread: 0x14d970990>{number = 2, name = (null)} read start 
2: 1443185739.020410, cost 0.593304, info: <NSThread: 0x14d970990>{number = 2, name = (null)} read end 

的成本达到0.5秒。

所以我混淆了多线程阅读会减慢sqlite3的性能。

据我所知,阅读使用shared-mutex,它可以在多线程中共享。性能下降不应该发生。

有人可以解决我的困惑吗?


附加:
sqlite3的是在WAL,SQLITE_CONFIG_MULTITHREAD模式,无需任何手动互斥。


附加:
我运行这样我在3个线程代码。

//objc code 
dispatch_async(name1, ^{ 
    select * in conn1 
} 
dispatch_async(name2, ^{ 
    select * in conn2 
} 
dispatch_async(name3, ^{ 
    select * in conn3 
} 
+0

而不是在每个线程中使用相同的连接(线程不能同时使用),请为每个线程创建一个连接。 –

+0

我明白每个线程都有自己的句柄sqlite(单线程一个句柄)。您正在以错误的方式使用线程。你让你的软件做了3次相同的工作,所以它花了更多的时间。 – user430051

+0

@ColonelThirtyTwo我在每个线程中都使用自己的连接。 (写单线程一连接) –

回答

0

这并不令人惊讶。你的所有线程都使用与数据库的共享连接,并对其进行同步。结果,在给定的时刻只有一个线程真正执行。添加上下文切换,并了解性能降低的原因。

如果您为每个线程提供自己的连接,则线程内不会进行同步,您应该看到性能得到提高。

+0

我在每个线程中都使用自己的连接。 (写成单线程连接) –

0

我试着用一个例子来回答。对于这种情况,客户端如何与服务器或上下文切换,虚拟化,多核等等进行对话并不重要(但请注意,在设计规范中的系统时需要考虑到这一点):

你有一个N客户端的服务器。客户来去,并有不同的要求。一些客户做出快速,小而频繁的请求。其他人减少需要更长时间才能返回的请求。

如果您有一个进程/线程,则一次只能处理一个客户端的一个请求 - 您有一堆客户端,每个客户端都有一堆请求。

现在,假设您想要使用线程来并行化您的工作负载,您可以为每个客户端分配一个线程(多种可能之一)。你将有一堆线程(每一个代表一个客户端)。然后每个线程都会有一堆客户请求。操作系统将在这些多个任务之间分割(上下文切换)处理时间,并且您将有一个连击总体响应。

你目前的方法并没有探索使用并行处理 - 你只是要求线程做同样的工作。

即便如此,单靠这些还不足以让代码线性增加时间。我怀疑在某个地方,你可能会分享相同的资源 - 这将是瓶颈。

你可以谷歌大量的材料何时使用线程。我发现了解线程的最佳资源之一是C10k problem。您可以找到纸here的归档版本。

相关问题