KSH:循环性能
KSH: Loop performance
我需要使用 ksh 处理具有以下格式的大约 120k 行的文件:
"[UserId=USER1]";"Client=001";"Locked_Status=0";"TYPE=A";"Last_Logon=00000000";"Valid_To=99991231";"Password_Change=20120131";"Last_Password_Change=29990"
"[UserId=USER2]";"Client=000";"Locked_Status=0";"TYPE=A";"Last_Logon=20141020";"Valid_To=00000000";"Password_Change=20140620";"Last_Password_Change=9501"
"[UserId=USER3]";"Client=002";"Locked_Status=0";"TYPE=A";"Last_Logon=00000000";"Valid_To=99991231";"Password_Change=20140304";"Last_Password_Change=9817"
输出应该是这样的:
[UserId=USER1] Client=001
Locked_Status=0
TYPE=A
Last_Logon=00000000
Valid_To=99991231
Password_Change=20120131
Last_Password_Change=29985
[UserId=USER2]
Client=000
Locked_Status=0
TYPE=A
Last_Logon=20141020
Valid_To=00000000
Password_Change=20140620
Last_Password_Change=9496
[UserId=User3]
Client=002
Locked_Status=0
TYPE=A
Last_Logon=00000000
Valid_To=99991231
Password_Change=20140304
Last_Password_Change=9812
我最初使用以下代码处理文件:
for a in $(<)
do
a=$(echo $a|sed -e 's/;/ /g' -e 's/"//g')
for b in $a
do
print $b
done
done
处理 120k 行大约需要 3 个小时。
然后我尝试改进代码,将其更改为以下内容:
for a in $(<)
do
printf "\n$(echo $a|sed -e 's/"//g' -e 's/;/\n/g')"
done
这给了我 2 小时的处理时间,但是处理 120k 行仍然需要很长时间
最后我尝试了这段代码,它在 3 秒内处理了 120k 行!
perl -ne '
chomp;
s/\"//g;
s/;/\n/g;
print;
' <
我是否可以改进 KSH 中的代码以实现类似的性能?我相信我的 KSH 代码中一定遗漏了一些东西......请帮我找出答案。
提前致谢
怎么样:
tr ';' '\n' < file | tr -d '"'
您的代码依次将每个以空格分隔的单词分配给变量"a",从而为文件中的每个单词调用一次sed
。显然,大量累积的开销产生了所有这些过程。遍历文件的 行 的习惯用法是:
while IFS= read -r line; do ...; done < file
您的建议非常有效
Host> wc -l /tmp/MyTest
114449 /tmp/MyTest
Host> time tr ';' '\n' < /tmp/MyTest | tr -d '"' > /tmp/zuza.out
real 0m1.04s
user 0m1.06s
sys 0m0.08s
Host> time perl -ne '
chomp;
s/\"//g;
s/;/\n/g;
print "\n$_";
' </tmp/MyTest > /tmp/zuza
real 0m1.30s
user 0m0.60s
sys 0m0.08s
我需要使用 ksh 处理具有以下格式的大约 120k 行的文件:
"[UserId=USER1]";"Client=001";"Locked_Status=0";"TYPE=A";"Last_Logon=00000000";"Valid_To=99991231";"Password_Change=20120131";"Last_Password_Change=29990"
"[UserId=USER2]";"Client=000";"Locked_Status=0";"TYPE=A";"Last_Logon=20141020";"Valid_To=00000000";"Password_Change=20140620";"Last_Password_Change=9501"
"[UserId=USER3]";"Client=002";"Locked_Status=0";"TYPE=A";"Last_Logon=00000000";"Valid_To=99991231";"Password_Change=20140304";"Last_Password_Change=9817"
输出应该是这样的:
[UserId=USER1] Client=001
Locked_Status=0
TYPE=A
Last_Logon=00000000
Valid_To=99991231
Password_Change=20120131
Last_Password_Change=29985
[UserId=USER2]
Client=000
Locked_Status=0
TYPE=A
Last_Logon=20141020
Valid_To=00000000
Password_Change=20140620
Last_Password_Change=9496
[UserId=User3]
Client=002
Locked_Status=0
TYPE=A
Last_Logon=00000000
Valid_To=99991231
Password_Change=20140304
Last_Password_Change=9812
我最初使用以下代码处理文件:
for a in $(<)
do
a=$(echo $a|sed -e 's/;/ /g' -e 's/"//g')
for b in $a
do
print $b
done
done
处理 120k 行大约需要 3 个小时。 然后我尝试改进代码,将其更改为以下内容:
for a in $(<)
do
printf "\n$(echo $a|sed -e 's/"//g' -e 's/;/\n/g')"
done
这给了我 2 小时的处理时间,但是处理 120k 行仍然需要很长时间
最后我尝试了这段代码,它在 3 秒内处理了 120k 行!
perl -ne '
chomp;
s/\"//g;
s/;/\n/g;
print;
' <
我是否可以改进 KSH 中的代码以实现类似的性能?我相信我的 KSH 代码中一定遗漏了一些东西......请帮我找出答案。
提前致谢
怎么样:
tr ';' '\n' < file | tr -d '"'
您的代码依次将每个以空格分隔的单词分配给变量"a",从而为文件中的每个单词调用一次sed
。显然,大量累积的开销产生了所有这些过程。遍历文件的 行 的习惯用法是:
while IFS= read -r line; do ...; done < file
您的建议非常有效
Host> wc -l /tmp/MyTest
114449 /tmp/MyTest
Host> time tr ';' '\n' < /tmp/MyTest | tr -d '"' > /tmp/zuza.out
real 0m1.04s
user 0m1.06s
sys 0m0.08s
Host> time perl -ne '
chomp;
s/\"//g;
s/;/\n/g;
print "\n$_";
' </tmp/MyTest > /tmp/zuza
real 0m1.30s
user 0m0.60s
sys 0m0.08s