我的代码遍历文件并将第一列中的所有数字乘以数字。代码有效,但我认为它有点慢。它需要26.676秒(壁挂时间)才能通过一个包含2302行的文件。我使用的是2.7 GHz Intel Core i5处理器。这是代码。
#!/bin/bash
i=2
sed -n 1p data.txt > data_diff.txt #outputs the header (x y)
while [ $i -lt 2303 ]; do
NUM=`sed -n "$i"p data.txt | awk '{print $1}'`
SEC=`sed -n "$i"p data.txt | awk '{print $2}'`
NNUM=$(bc <<< "$NUM*0.000123981")
echo $NNUM $SEC >> data_diff.txt
let i=$i+1
done
答案 0 :(得分:5)
老实说,你可以获得的最大加速来自于使用可以完成整个任务的单一语言。这主要是因为你的脚本为每个行调用了5个额外的进程,并且调用额外的进程很慢,但是bash中的文本处理实际上并没有那么好地优化。
我推荐awk,因为你有它可用:
awk '{ print $1*0.000123981, $2 }'
我确信你可以改进这一点,跳过标题行并不加修改地打印出来。
你也可以使用Perl,Python,C,Fortran和许多其他语言来做这类事情,尽管这种简单的计算不太可能有太大的区别。
答案 1 :(得分:4)
您的脚本运行4603个单独的sed
进程,4602个单独的awk
进程和2301个单独的bc
进程。如果echo
不是内置的,那么它也会运行2301 echo
个进程。启动进程的开销相对较大。没有那么大,你通常会注意到它,但你运行超过11000个短流程。壁挂时间的消耗似乎并不合理。
此外,您运行的每个sed
都会重新处理整个输入文件,只选择一行。这非常低效。
解决方案是减少正在运行的进程数,尤其是只对整个输入文件执行一次运行。一个相当简单的方法是转换为awk
脚本,可能使用bash
包装器。这可能看起来像这样:
#!/bin/bash
awk '
NR==1 { print; next }
NR>=2303 { exit }
{ print $1 * 0.000123981, $2 }
' data.txt > data_diff.txt
请注意,以NR>=2303
开头的行在到达第2303行时会人为地停止处理输入文件,就像原始脚本一样;你可以完全省略脚本的那一行,让它只是处理所有的行,无论有多少行。
请注意,它使用awk
的内置FP算法而不是运行bc
。如果你真的需要bc
的任意精度算术,那么我相信你可以弄清楚如何修改脚本来实现它。
答案 2 :(得分:3)
作为如何加速rebootInstances
脚本的示例(并不意味着这是正确的解决方案)
bash
现在,每个数据行只需要对#!/bin/bash
{ IFS= read -r header
echo "$header"
# You can drop the third name "rest" if your input file
# only has two columns.
while read -r num sec rest; do
nnum=$( bc <<< "$num * 0.000123981" )
echo "$nnum $sec"
done
} < data.txt > data_diff.txt
进行一次额外调用,因为bc
不执行浮点运算。正确的答案是使用单个调用来编程可以执行浮点运算,正如David Z所指出的那样。