我的图书馆的变化使它变慢了很多。分析对我没有帮助。速度缓慢的原因可能是什么?

2024-03-28

我的问题,简述

我对我的库进行了更改,现在速度慢得多,但我无法弄清楚它在哪里花费了所有额外的时间。分析报告没有帮助。请帮我看看可能是什么原因。

一些背景

我创建了一个 Redis 客户端库,名为Hedis http://hackage.haskell.org/package/hedis并为其制定一个基准计划。现在,我对库进行了一些内部更改,以清理架构。这导致性能(以每秒 Redis 请求数为单位,根据上述基准测试)下降约 2.5 倍。

该基准测试打开 50 个到本地主机上的 Redis 服务器的网络连接。两个版本之间的连接处理方式不同:

  • 快速版本每个连接使用一个线程(因此,基准测试有 50 个并发运行的线程)。它从套接字读取 通过使用处理unsafeInterleaveIO(我广泛地描述了我的方法 中风博客文章在这里 http://informatikr.com/2012/redis-pipelining.html)。我有点不高兴 与架构,因此我改变了事情
  • 慢速版本每个连接使用三个线程。他们通过两个方式进行交流Chans(基准测试中运行 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 -sflag 将此报告为生产力下降。

以下是两个版本的程序输出+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

您有什么想法或提示可以从哪里获得额外的时间吗?


根据分析报告,大部分时间花在hFlush and hGetSome。根据time,慢速版本需要更多的系统时间。所以,我的假设是,大量时间花费在阻塞和等待上,无论是等待更多输入还是锁定和解锁线程。

这是我要做的第一件事:编译代码-threaded看看会发生什么。线程运行时使用完全不同的 IO 管理器,我强烈怀疑这一单一更改将解决您的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的图书馆的变化使它变慢了很多。分析对我没有帮助。速度缓慢的原因可能是什么? 的相关文章

随机推荐