我的问题,简述
我对我的库进行了更改,现在速度慢得多,但我无法弄清楚它在哪里花费了所有额外的时间。分析报告没有帮助。请帮我看看可能是什么原因。
一些背景
我创建了一个 Redis 客户端库,名为Hedis http://hackage.haskell.org/package/hedis并为其制定一个基准计划。现在,我对库进行了一些内部更改,以清理架构。这导致性能(以每秒 Redis 请求数为单位,根据上述基准测试)下降约 2.5 倍。
该基准测试打开 50 个到本地主机上的 Redis 服务器的网络连接。两个版本之间的连接处理方式不同:
-
快速版本每个连接使用一个线程(因此,基准测试有 50 个并发运行的线程)。它从套接字读取
通过使用处理
unsafeInterleaveIO
(我广泛地描述了我的方法
中风博客文章在这里 http://informatikr.com/2012/redis-pipelining.html)。我有点不高兴
与架构,因此我改变了事情
-
慢速版本每个连接使用三个线程。他们通过两个方式进行交流
Chan
s(基准测试中运行 150 个线程)。
更多可能相关的信息:
- 使用 GHC 7.2.2 编译。
- 两个版本之间的基准测试程序没有变化,因此网络
流量是一样的。
- 两个版本都使用单线程运行时(编译without
-threaded
).
- 所有线程都是通过调用创建的
forkIO
. Not越贵forkOS
.
分析结果
分析并没有给我提供性能下降的明确原因。根据分析报告,两个版本 99% 以上的时间都花在System.IO.hFlush
and Data.ByteString.hGetSome
。次数hFlush
and hGetSome
两个版本中的名称相同。由于两种情况下的网络流量也相同,因此这些功能不能成为速度变慢的原因。
我可以衡量两个版本之间唯一显着的差异是什么time
(Unix 实用程序)告诉我:与快速版本相比,慢速版本(线程数是其三倍)在“sys”而不是“user”上花费的时间明显更多。全球HC+RTS -s
flag 将此报告为生产力下降。
以下是两个版本的程序输出+RTS -s
flag:
快速版本的基准
$ time ./dist/build/hedis-benchmark/hedis-benchmark +RTS -s -p
ping 33305.29 Req/s
get 25802.92 Req/s
mget 18215.94 Req/s
ping (pipelined) 268994.36 Req/s
5,118,163,904 bytes allocated in the heap
185,075,608 bytes copied during GC
4,084,384 bytes maximum residency (39 sample(s))
916,544 bytes maximum slop
10 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 7416 colls, 0 par 0.38s 0.40s 0.0001s 0.0003s
Gen 1 39 colls, 0 par 0.03s 0.03s 0.0007s 0.0009s
INIT time 0.00s ( 0.00s elapsed)
MUT time 7.93s ( 12.34s elapsed)
GC time 0.41s ( 0.43s elapsed)
RP time 0.00s ( 0.00s elapsed)
PROF time 0.00s ( 0.00s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 8.33s ( 12.76s elapsed)
%GC time 4.9% (3.3% elapsed)
Alloc rate 645,587,554 bytes per MUT second
Productivity 95.1% of total user, 62.1% of total elapsed
real 0m12.772s
user 0m8.334s
sys 0m4.424s
慢速版本的基准
$ time ./dist/build/hedis-benchmark/hedis-benchmark +RTS -s -p
ping 11457.83 Req/s
get 11169.64 Req/s
mget 8446.96 Req/s
ping (pipelined) 130114.31 Req/s
6,053,055,680 bytes allocated in the heap
1,184,574,408 bytes copied during GC
9,750,264 bytes maximum residency (198 sample(s))
2,872,280 bytes maximum slop
26 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 9105 colls, 0 par 2.11s 2.14s 0.0002s 0.0006s
Gen 1 198 colls, 0 par 0.23s 0.24s 0.0012s 0.0093s
INIT time 0.00s ( 0.00s elapsed)
MUT time 10.99s ( 27.92s elapsed)
GC time 2.34s ( 2.38s elapsed)
RP time 0.00s ( 0.00s elapsed)
PROF time 0.00s ( 0.00s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 13.33s ( 30.30s elapsed)
%GC time 17.6% (7.8% elapsed)
Alloc rate 550,656,490 bytes per MUT second
Productivity 82.4% of total user, 36.3% of total elapsed
real 0m30.305s
user 0m13.333s
sys 0m16.964s
您有什么想法或提示可以从哪里获得额外的时间吗?