这是用awk打印的最快方式

时间:2016-04-27 06:29:58

标签: shell unix awk printf ksh

我正在尝试进行一些测量,我想知道通过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} }

2 个答案:

答案 0 :(得分:3)

程序运行缓慢的原因不在于打印。您的程序很慢,因为您为nawk的每个元素调用了$NUMBERS的新副本。这非常浪费,您应该从一开始就重新考虑您的程序设计。看起来你大多试图看到第二个列表中存在一个列表中的哪些数字。如果你想在nawk中执行此操作,则应首先读取整个第一个列表,并在从第二个文件中读取每个数字之前将元素存储在关联数组中。

您可以使用joingrep更清晰地解决此问题。

编辑:这是使用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中)列表