哪一个对浮动操作,awk或bc更有效?

时间:2012-11-24 11:42:18

标签: linux performance bash awk bc

我正在用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 个答案:

答案 0 :(得分:4)

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

这是你的第二个例子。

但是你可以通过消除grep

来使它变得更简单
CPU=$(mpstat 1 1 | awk '/Average/{print 100 - $11}')

答案 1 :(得分:2)

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

仅使用bc,不使用awk,请尝试:

CPU=$(mpstat 1 1 | grep Average | { read -a P; echo 100 - ${P[10]}; } | bc )

答案 2 :(得分:0)

感谢所有人在awk / bc上教育我! 做了基准(希望更合适的方式):
tl; dr:awk wins

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

全文:

[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时分支更多进程的开销有关。

答案 3 :(得分:-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秒。显然它没有任何区别。