1

我正在用 bash 编写系统性能脚本。我想以百分比计算 CPU 使用率。我有两种实现,一种使用 awk,另一种使用 bc。我想知道这两个版本中哪个更有效。使用 awk 或 bc 进行浮点计算更好吗?谢谢!

版本 #1(使用 bc)

CPU=$(mpstat 1 1 | grep "Average" | awk '{print $11}')
CPU=$(echo "scale=2;(100-$CPU)" | bc -l)
echo $CPU

版本 #2(使用 awk)

CPU=$(mpstat 1 1 | grep "Average" | awk '{idle = $11} {print 100 - idle}')
echo $CPU
4

4 回答 4

4

由于两者的处理时间都很短,产生最少进程和子shell的版本将“更有效”。

这是你的第二个例子。

但是您可以通过消除grep

CPU=$(mpstat 1 1 | awk '/Average/{print 100 - $11}')
于 2012-11-24T11:50:44.153 回答
2

在版本 1 中,为什么需要第二行?为什么你不能从第一行本身做呢?我问是因为,第一个版本是 grep+awk+bc;第二个例子是 grep+awk。所以我认为这种比较是无效的。

对于只使用 bc 而没有 awk,试试这个:

CPU=$(mpstat 1 1 | grep Average | { read -a P; echo 100 - ${P[10]}; } | bc )
于 2012-11-24T12:09:31.880 回答
0

感谢大家对我进行 awk/bc 的教育!
做了基准测试(希望以更正确的方式):
tl;博士:awk 获胜

半长的故事:
3 次 1000 次运行 awk 在我的系统上平均为 2.081333s,而 bc 平均为 3.460333s

完整的故事:

[me@thebox tmp]$ time for i in `seq 1 1000` ; do echo "Average:     all    5.05    0.00    6.57    0.51    0.00    0.00    0.00    0.00   87.88" | awk '/Average/ {print 100 - $11}' >/dev/null ; done

real    0m1.922s
user    0m0.320s
sys     0m1.308s
[me@thebox tmp]$ time for i in `seq 1 1000` ; do echo "Average:     all    5.05    0.00    6.57    0.51    0.00    0.00    0.00    0.00   87.88" | awk '/Average/{print 100 - $11}' >/dev/null ; done

real    0m2.124s
user    0m0.370s
sys     0m1.368s
[me@thebox tmp]$ time for i in `seq 1 1000` ; do echo "Average:     all    5.05    0.00    6.57    0.51    0.00    0.00    0.00    0.00   87.88" | awk '/Average/{print 100 - $11}' >/dev/null ; done

real    0m2.198s
user    0m0.412s
sys     0m1.383s

[me@thebox tmp]$ time for i in `seq 1 1000` ; do echo "Average:     all    5.05    0.00    6.57    0.51    0.00    0.00    0.00    0.00   87.88" | grep Average | { read -a P; echo 100 - ${P[10]}; } | bc >/dev/null ; done

real    0m3.799s
user    0m0.691s
sys     0m3.059s
[me@thebox tmp]$ time for i in `seq 1 1000` ; do echo "Average:     all    5.05    0.00    6.57    0.51    0.00    0.00    0.00    0.00   87.88" | grep Average | { read -a P; echo 100 - ${P[10]}; } | bc >/dev/null ; done

real    0m3.545s
user    0m0.604s
sys     0m2.801s
[me@thebox tmp]$ time for i in `seq 1 1000` ; do echo "Average:     all    5.05    0.00    6.57    0.51    0.00    0.00    0.00    0.00   87.88" | grep Average | { read -a P; echo 100 - ${P[10]}; } | bc >/dev/null ; done

real    0m3.037s
user    0m0.602s
sys     0m2.626s
[me@thebox tmp]$

在没有进一步追踪的情况下,我相信这与使用 bc 时分叉更多进程的开销有关。

于 2016-08-02T08:12:04.680 回答
-1

我做了以下基准测试:

#!/bin/bash

count=0
tic="$(date +%s)"
while [ $count -lt 50 ]
do
mpstat 1 1 | awk '/Average/{print 100 - $11}'
count=$(($count+1))
done
toc="$(date +%s)"
sec="$(expr $toc - $tic)"

count=0
tic="$(date +%s)"
while [ $count -lt 50 ]
do
CPU=$(mpstat 1 1 | grep "Average" | awk '{print $11}')
echo "scale=2;(100-$CPU)" | bc -l
count=$(($count+1))
done
toc="$(date +%s)"
sec1="$(expr $toc - $tic)"

echo "Execution Time awk: "$sec
echo "Execution Time bc: "$sec1

两个执行时间是相同的...... 50 秒。显然它没有任何区别。

于 2012-11-24T12:39:17.283 回答