测量小型应用程序的性能

2024-10-05 14:25:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我为Sway WM(https://swaywm.org)编写了一个状态栏,基本上每秒打印一些信息(loadavg、cpu使用情况、内存使用情况、时间等等)

该项目(https://gitlab.com/Yellowhat/statusbar)纯粹是为了学习CI/CD以及如何衡量性能(如果可能,在嘈杂的环境中)

最初这个项目都是用python写的,但不久前我决定用rusthttps://gitlab.com/Yellowhat/statusbar/-/tree/master/tools/rust)写一个功能上等价的(它们打印出完全相同的信息)

查看每秒执行的指令数(I refs使用cachegrind,精简版本):

  • python:~800k
  • rust:~35k

我可以得出结论rust版本比python版本“轻”得多

由于系统运行时状态栏将持续运行,因此我想了解它对系统的影响。因此,我决定在空闲时使用以下python脚本监控我的系统(1小时内不要触摸电脑,100%亮度):

from time import sleep

while True:
    stat = open("/proc/stat").readlines()[0].split()[1:8]
    power = float(open("/sys/class/power_supply/BAT0/power_now").read().strip()) / 10**6
    print(f"{stat},{power}")
    sleep(1)
  • /proc/stat返回在以下方面花费的CPU时间(jiffies):
    • user:在用户模式下执行的正常进程
    • nice:在用户模式下执行的niced进程
    • system:在内核模式下执行的进程
    • idle:玩弄拇指
    • iowait:正在等待I/O完成
    • irq:为中断提供服务
    • softirq:为软件IRQ提供服务
  • /sys/class/power_supply/BAT0/power_now返回电池的电量(微瓦)

我比较了4个案例:

  1. tty:从tty启动计算机并运行脚本
  2. sway:启动计算机,启动sway(无条),打开终端并运行脚本
  3. sway barpy:启动计算机,启动sway(使用python版本),打开终端并运行脚本
  4. sway barrs:启动计算机,启动sway(使用rust版本),打开终端并运行脚本

下图显示了SUM(user_t, nice_t, system_t, iowait_t, irq_t, softirq_t) - SUM(user_t0, nice_t0, system_t0, iowait_t0, irq_t0, softirq_t0)(所有CPU未空闲时花费的时间)-(测试开始时的初始值)与4种情况下的时间的对比:

CPU Time

正如您所看到的,tty最低,其次是sway,但有趣的是rust版本比python版本高得多

下图显示了4种情况下的功率与时间的关系:

Power

如您所见,tty的消耗量最低,其次是sway,最后非常接近rustpython。这是我所期望的结果

第一个图表表明,在本例中,rust不比python

是否有更可靠的方法来测量“光”应用? 我是否误解了/proc/stat的内容

谢谢

更新1

下图显示了user_t - user_t0nice_t - nice_t0system_t - system_t0pythonrust时间的关系:

User, Nice, System

user是相似的,而systemnicerust要高得多

更新2

根据Peter Cordes的建议,我已经运行了:

perf stat -a -d -e cpu-cycles,cycles,cycles:u,instructions,instructions:u -r 10 <binary>

下表总结了结果:

^{tb1}$

删除初始值(持续时间=0)并除以持续时间:

^{tb2}$

同样,似乎rust版本比python版本运行的周期/指令更多

更新3

$ valgrind \
    --tool=cachegrind \
    --cachegrind-out-file=/dev/null \
    --trace-children=yes \
    --I1=32768,8,64 \
    --D1=32768,8,64 \
    --LL=8388608,16,64 \
    --cache-sim=yes \
    --branch-sim=yes \
    <binary>

运行120秒:

  • python版本:
I   refs:      328,117,776
I1  misses:      5,268,249
LLi misses:         15,274
I1  miss rate:        1.61%
LLi miss rate:        0.00%

D   refs:      135,851,173  (95,116,936 rd   + 40,734,237 wr)
D1  misses:      4,717,331  ( 4,145,263 rd   +    572,068 wr)
LLd misses:        167,298  (    57,266 rd   +    110,032 wr)
D1  miss rate:         3.5% (       4.4%     +        1.4%  )
LLd miss rate:         0.1% (       0.1%     +        0.3%  )

LL refs:         9,985,580  ( 9,413,512 rd   +    572,068 wr)
LL misses:         182,572  (    72,540 rd   +    110,032 wr)
LL miss rate:          0.0% (       0.0%     +        0.3%  )

Branches:       60,115,083  (56,103,351 cond +  4,011,732 ind)
Mispredicts:     5,661,255  ( 4,245,148 cond +  1,416,107 ind)
Mispred rate:          9.4% (       7.6%     +       35.3%   )
  • rust版本:
I   refs:      100,950,027
I1  misses:        351,835
LLi misses:          5,859
I1  miss rate:        0.35%
LLi miss rate:        0.01%

D   refs:       44,227,512  (24,903,985 rd   + 19,323,527 wr)
D1  misses:        670,307  (   341,521 rd   +    328,786 wr)
LLd misses:         34,962  (    20,657 rd   +     14,305 wr)
D1  miss rate:         1.5% (       1.4%     +        1.7%  )
LLd miss rate:         0.1% (       0.1%     +        0.1%  )

LL refs:         1,022,142  (   693,356 rd   +    328,786 wr)
LL misses:          40,821  (    26,516 rd   +     14,305 wr)
LL miss rate:          0.0% (       0.0%     +        0.1%  )

Branches:       19,868,173  (18,608,630 cond +  1,259,543 ind)
Mispredicts:     1,289,209  (   771,555 cond +    517,654 ind)
Mispred rate:          6.5% (       4.1%     +       41.1%   )

Tags: 版本rate时间rdrustwrstatpower