You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sway状态栏Python与Rust版本性能异常及轻量应用测量方法咨询

我为Sway WM(https://swaywm.org)编写了一款状态栏,基本功能是每秒打印系统负载、CPU使用率、内存使用率、时间等信息。
该项目(https://gitlab.com/Yellowhat/statusbar)的初衷是学习CI/CD及高干扰环境下的性能测量方法。
项目最初完全用python编写,后来我又用rust实现了功能完全一致的版本(https://gitlab.com/Yellowhat/statusbar/-/tree/master/tools/rust),两个版本输出的信息完全相同。

通过简化版cachegrind统计每秒执行的指令数I refs结果如下:

  • python版本:约80万条
  • rust版本:约3.5万条

按该结果我原本认为rust版本远轻于python版本。
由于状态栏会随系统持续运行,我希望明确其对系统的影响,因此编写了如下python脚本,在系统idle状态(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:用户态下调整过nice值的进程执行时间
    • system:内核态进程执行时间
    • idle:空闲时间
    • iowait:等待I/O完成的时间
    • irq:处理硬中断的时间
    • softirq:处理软中断的时间
  • /sys/class/power_supply/BAT0/power_now返回电池的实时输出功率(单位微瓦)

我对比了4种测试场景:

  1. tty:开机后直接在tty中运行监控脚本
  2. sway:开机后启动无状态栏的sway,打开终端运行监控脚本
  3. sway barpy:开机后启动搭载python版状态栏的sway,打开终端运行监控脚本
  4. sway barrs:开机后启动搭载rust版状态栏的sway,打开终端运行监控脚本

下图展示了4种场景下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非空闲时间累计值减去测试初始值)随时间的变化趋势:
CPU Time

结果显示tty场景非空闲时间最低,其次是无状态栏的sway场景,但出人意料的是rust版状态栏的非空闲时间远高于python版本。
下图展示了4种场景下功耗随时间的变化趋势:
Power

结果显示tty场景功耗最低,其次是无状态栏的sway场景,rust版功耗略高于后者,python版功耗最高,符合我的预期。
第一张CPU时间图的结果说明该场景下rust版本并不比python版本更轻量。
请问是否有更可靠的方法测量应用的轻量程度?我是否对/proc/stat的内容存在误解?

更新1

下图展示了python和rust版本的user_t - user_t0、nice_t - nice_t0、system_t - system_t0随时间的变化趋势:
User, Nice, System

两者的user态时间相近,但rust版本的system和nice态时间远高于python版本。

更新2

按照Peter Cordes的建议我执行了如下命令:

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

结果汇总如下表:

版本测试时长cpu-cyclescyclescycles:uinstructionsinstructions:u
python0285,248,768285,492,709215,681,759323,852,866278,792,657
python603,038,749,6103,046,770,4771,360,477,4722,425,399,5881,612,134,730
python1205,802,965,8745,818,929,4892,496,192,0624,536,305,4432,890,941,664
rust01,165,2231,165,869304,1881,319,168442,565
rust603,791,712,5163,799,515,5231,654,232,5373,355,917,4232,073,096,815
rust1207,878,549,5707,897,534,2783,341,698,2826,665,643,0644,144,148,632

扣除测试初始值(时长=0时的数值)并除以测试时长后,结果如下:

版本测试时长cpu-cyclescyclescycles:uinstructionsinstructions:u
python6045,891,68146,021,29619,079,92935,025,77922,222,368
python12045,980,97646,111,97319,004,25335,103,77121,767,908
rust6063,175,78863,305,82827,565,47255,909,97134,544,238
rust12065,644,87065,803,07027,844,95155,536,03234,530,884

结果再次显示rust版本每秒消耗的CPU周期和执行的指令数均高于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%   )

内容的提问来源于stack exchange,提问作者yellowhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:06:06