我正在尝试进行一些测量,我想知道通过nawk
打印内容的最快方法是什么。
目前我使用的是printf ARR[2] " ";
,但打印时似乎需要更多时间。
信息:我正在打印约500个数字并在printf
中添加空格,这样就不会在打印输出中将所有内容粘在一起。我也在unix oracle solaris上运行ksh上的脚本。
像这样,它需要大约14秒来打印所有内容,有没有更快的方法可以做到这一点?
提前致谢!
更新
我关心的功能是awkfun,因为我在调用它时使用time
来进行时间测量。
将NUMBERS
视为包含1000个随机数的变量,将XNUMBERS
视为包含1000个随机数的变量,但采用此格式123|321
,因此需要随机数来反映它并添加中间有一个|
。
我正在检查NUMBERS
中的每一个XNUMBERS
是否在numfun() {
NUMBERS=`nawk ' BEGIN{
srand();
for (i=0; i<=999; i++) {
printf("%s\n", 100 + int(rand() * (899)));
}
}'`
}
numfun
sleep 1
xnumfun() {
XNUMBERS=`nawk ' BEGIN{
srand();
for (i=0; i<=999; i++) {
XNUMBERS[i]= 100 + int(rand() * (899));
}
for (i=0; i<=999; i++) {
ver=XNUMBERS[i] "";
rev = "";
for (q=length(ver); q!=0; q--) {
rev = rev substr(ver, q, 1);
}
printf("%s\n", XNUMBERS[i] "|" rev );
}
}'`
}
xnumfun
awkfun() {
for n in $NUMBERS
do
echo "${XNUMBERS}" | nawk -v VAR=$n '
{
split($1,ARR,"|")
if (VAR == ARR[1]){
printf ARR[2] " ";
exit;
}
}'
done
}
shellfun() {
for n in $NUMBERS
do
for x in $XNUMBERS
do
if test "$n" -eq "${x%%\|*}"
then
echo "${x##*\|}";
break;
fi
continue;
done
done
}
sleep 1
time awkfun;
echo "\nAWK TIME\n\n-----------------------------";
time shellfun;
echo "\nSHELL TIME\n\n-----------------------------";
time numfun;
echo "\nNUMBERS TIME\n\n-----------------------------";
time xnumfun;
echo "\nXNUMBERS TIME\n\n-----------------------------\n\nTOTAL TIME\n";
中出现,如果它是exhists我只打印出反转的数字。
0,84
结果
作为参考,对于完善脚本后的结果, AWK 平均实时= 0,48
, SHELL 平均实时:{{1} }
答案 0 :(得分:3)
程序运行缓慢的原因不在于打印。您的程序很慢,因为您为nawk
的每个元素调用了$NUMBERS
的新副本。这非常浪费,您应该从一开始就重新考虑您的程序设计。看起来你大多试图看到第二个列表中存在一个列表中的哪些数字。如果你想在nawk中执行此操作,则应首先读取整个第一个列表,并在从第二个文件中读取每个数字之前将元素存储在关联数组中。
您可以使用join
或grep
更清晰地解决此问题。
编辑:这是使用grep
的有效解决方案。它比原始shellfun()
快至少20倍。
shellfun2() {
echo $XNUMBERS | tr ' ' '\n' | cut -d '|' -f1 \
| grep -f <(echo $NUMBERS | tr ' ' '\n') | rev
}
它的工作方式是从管道前$XNUMBERS
获取所有数字(12|21 34|43
变为12\n34
),然后用{grep
将其传递给-f
1}}参数全是$NUMBERS
。这意味着我们会在$XNUMBERS
内搜索$NUMBERS
的所有左侧,并且在打印匹配后,我们只需使用rev
来反转它们。我们根本不需要$XNUMBERS
的右侧(因此,您甚至可以在第一时间停止生成它们,从而节省更多时间)。
编辑:既然你现在告诉我们你在Solaris而不是Linux上运行,那么你没有rev
,所以你可以用以下内容替换上面的rev
:
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
您可以将grep
替换为/usr/xpg4/bin/grep
,以获得支持-f
的增强版。
答案 1 :(得分:2)
你要为$ NUMBERS中的每个号码发起nawk,这在时间上非常昂贵。
你可以用grep过滤$NUMBERS
只能处理你感兴趣的数字。即
grep -f FileWithListOfNumbers FileWithListOfXnumbers >matched_numbers
会为您提供一份也在NUMBERS中的XNUMBERS(在matched_numbers中)列表