1
set fr [open "x.txt" r]
set fw [open "y.txt" w]
set myRegex {^([0-9]+) ([0-9:]+\.[0-9]+).* ABC\.([a-zA-Z]+)\[([0-9]+)\] DEF\(([a-zA-Z]+)\) HIJ\(([0-9]+)\) KLM\(([0-9\.]+)\) NOP\(([0-9]+)\) QRS\(([0-9]+)\)}
while { [gets $fr line] >= 0 } {
   if { [regexp $myRegex $line match x y w z]} {
       if { [expr $D >> 32] == [lindex $argv 0]} {
         puts $fw "$x"
       }
   }
}
close $fr $fw

上記の Tcl コードのビットは、実行に永遠に (32 秒以上) かかります。基本的に同じことを perl で実行すると、3 秒以内に実行されます。一部の正規表現では perl の方がパフォーマンスが優れていることは知っていますが、比較すると、tcl のパフォーマンスは本当にこれほど悪いのでしょうか? 10倍以上悪い?

ちなみにTCL8.4を使っています。

上記のコードを正規表現と同じ正規表現の縮小バージョンで実行した場合のメトリックは次のとおりです。

32s is the time taken for the above code to execute
22s after removing: QRS\(([0-9]+)\) 
17s after removing: NOP\(([0-9]+)\) QRS\(([0-9]+)\)
13s after removing: KLM\(([0-9\.]+)\) NOP\(([0-9]+)\) QRS\(([0-9]+)\)
9s  after removing: HIJ\(([0-9]+)\) KLM\(([0-9\.]+)\) NOP\(([0-9]+)\) QRS\(([0-9]+)\)
6s  after removing: DEF\(([a-zA-Z]+)\) HIJ\(([0-9]+)\) KLM\(([0-9\.]+)\) NOP\(([0-9]+)\) QRS\(([0-9]+)\)}
4

1 に答える 1

6

問題は、その RE で多くのキャプチャとバックトラックがあることです。その特定の組み合わせは、Tcl RE エンジンではうまく機能しません。あるレベルでの原因は、Tcl が Perl とはまったく異なるタイプの RE エンジンを使用していることです (ただし、他の RE ではうまく機能しますが、この領域は自明ではありません)。

可能であれば.*、RE から早期に削除してください:

^([0-9]+) ([0-9:]+\.[0-9]+).* ABC\.([a-zA-Z]+)\[([0-9]+ )\] DEF\(([a-zA-Z]+)\) HIJ\(([0-9]+)\) KLM\(([0-9\.]+)\) NOP\(( [0-9]+)\) QRS\(([0-9]+)\)
                           ^^

それがトラブルの本当の原因です。次のように、より正確なものに置き換えます。

(?:[^A]|A[^B]|AB[^C])*

また、RE 内のキャプチャ グループの数を必要な数だけ減らします。おそらく、コード全体を次のように変換できます。

set fr [open "x.txt" r]
set fw [open "y.txt" w]
set myRegex {^([0-9]+) (?:[0-9:]+\.[0-9]+)(?:[^A]|A[^B]|AB[^C])* ABC\.(?:[a-zA-Z]+)\[([0-9]+)\] DEF\((?:[a-zA-Z]+)\) HIJ\((?:[0-9]+)\) KLM\((?:[0-9\.]+)\) NOP\((?:[0-9]+)\) QRS\((?:[0-9]+)\)}
while { [gets $fr line] >= 0 } {
    # I've combined the [if]s and the [expr]
    if { [regexp $myRegex $line -> A D] && $D >> 32 == [lindex $argv 0]} {
        puts $fw "$A"
    }
}
close $fr $fw

if { [expr ...] }また、ブレースで囲まれていない式と同様に、疑わしいコードの匂いであることに注意してください。(非常に特殊な状況で必要になることもありますが、ほとんどの場合、コードが複雑すぎることを示しています。)

于 2013-08-13T12:28:02.257 に答える