我有一个 8400 万行的 XML,我正在 Red Hat Linux 中用“gawk”处理它。 (好吧,有些人会建议使用其他工具而不是 GAWK,但我的 XML 没有多行标记或任何其他使 GAWK 不是这项工作的好选择的特性。)我关心的是性能。我最初的 AWK 脚本是这样的:# Test_1.awkBEGIN {FS = "<|:|=";}{if ($3 == "SubNetwork id") { # do something }}END {# print something}这进行了 8400 万次字符串比较,每行一次。我注意到“SubNetwork id”仅在行中有 4 个字段 (NF=4) 时出现,因此我更改了脚本以减少字符串比较:# Test_2.awkBEGIN {FS = "<|:|=";}{if (NF == 4) { if ($3 == "SubNetwork id") { # do something } }}END {# print something}我运行它,看到我检查了 'NF == 4' 8400 万次(很明显),'$3 == "SubNetwork id"' 只检查了 300 万次。太好了,我减少了字符串比较的次数,我一直认为这比简单的整数比较更耗时(NF 是一个整数,对吧?)。当我测试这两个脚本的性能时,我感到惊讶。大多数时候 Test_1 比 Test_2 快。我多次运行它们以考虑可能使用 CPU 时间的其他进程,但总的来说,我的测试是在 CPU 或多或少“空闲”时运行的。我的大脑告诉我,8400 万次整数比较加上 300 万次字符串比较肯定比 8400 万次字符串比较快,但显然我的推理有问题。我的 XML 看起来像这样:<?xml version="1.0" encoding="UTF-8"?><ConfigDataFile xmlns:un="specific.xsd" xmlns:xn="generic.xsd"> <configData dnPrefix="Undefined"> <xn:SubNetwork id="ROOT_1"> <xn:SubNetwork id="ROOT_2"> <xn:attributes> ... </xn:attributes> </xn:SubNetwork> <xn:SubNetwork id="ID_1"> .... </xn:SubNetwork> <xn:SubNetwork id="ID_2"> ..... </xn:SubNetwork> </xn:SubNetwork> </configData></ConfigDataFile>任何有助于理解此性能问题的帮助将不胜感激。提前致谢。 最佳答案 我做了更多的测试:1- 生成一个包含一些数据的大文件yes 'SomeSampleText SomeOtherText 33 1970 YetAnotherText 777 abc 1 AndSomeMore' | head -12000000 > SomeData.txt分隔符是空格!2- 多次运行这 6 个测试,并计算每个测试的平均时间。我在 3 台不同的机器上做到了(使用 Red Hat Linux Enterprise 4)time gawk 'BEGIN {a = 0;} {if ($5 == "YetAnotherText") a ++;} END {print "a: " a;}' SomeData.txttime gawk 'BEGIN {a = 0;} {if ($0 ~ /YetAnotherText/) a ++;} END {print "a: " a;}' SomeData.txttime gawk 'BEGIN {a = 0;} /YetAnotherText/ {a ++;} END {print "a: " a;}' SomeData.txttime gawk 'BEGIN {a = 0;} {if (NF == 9) a ++;} END {print "a: " a;}' SomeData.txttime gawk 'BEGIN {a = 0;} {if ($1 == "SomeSampleText") a ++;} END {print "a: " a;}' SomeData.txttime gawk 'BEGIN {a = 0;} {if ($9 == "AndSomeMore") a ++;} END {print "a: " a;}' SomeData.txt3- 我得到了这些结果(数字是秒)-- Machine 110.3539.3938.8710.407.7212.26-- Machine 28.5032.4331.839.106.549.91-- Machine 312.3513.5512.9014.409.4314.93看起来在测试 2 和 3 中搜索模式/YetAnotherText/非常慢。除了机器 3...4-生成另一个大文件,其中包含一些具有不同分隔符的数据yes "<SomeSampleText:SomeOtherText=33>1970<YetAnotherText:777=abc>1<AndSomeMore>" | head -12000000 > SomeData2.txt5- 运行 6 个测试,更改 FStime gawk 'BEGIN {FS = "<|:|=";} {if ($5 == "YetAnotherText") a ++;} END {print "a: " a;}' SomeData2.txttime gawk 'BEGIN {FS = "<|:|=";} {if ($0 ~ /YetAnotherText/) a ++;} END {print "a: " a;}' SomeData2.txttime gawk 'BEGIN {FS = "<|:|=";} /YetAnotherText/ {a ++;} END {print "a: " a;}' SomeData2.txttime gawk 'BEGIN {FS = "<|:|=";} {if (NF == 8) a ++;} END {print "a: " a;}' SomeData2.txttime gawk 'BEGIN {FS = "<|:|=";} {if ($2 == "SomeSampleText") a ++;} END {print "a: " a;}' SomeData2.txttime gawk 'BEGIN {FS = "<|:|=";} {if ($8 == "AndSomeMore>") a ++;} END {print "a: " a;}' SomeData2.txt6- 我得到了这些结果(我只为机器 3 做了,抱歉)66.1733.1132.1676.7737.1777.20我的结论(另见@user31264 的评论): 似乎当有一个简单的分隔符而不是几个分隔符时,解析和拆分为字段的速度更快。 通常得到 $N 比得到 $M 更快,其中 N 在某些情况下,在整行中搜索/pattern/比比较 $N == "pattern"更快,特别是如果 N 不是该行的第一个字段 获取 NF 可能很慢,因为必须解析行并计算字段,如果有多个分隔符,则更是如此关于performance - AWK/GAWK 性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43513975/ 10-09 08:57