一般来说,您应该将您的代码放在一个过程中,以便从 Tcl 中获得最佳性能。(您在 8.5 和 8.6 中还有一些相关选项,例如 lambda 术语和类方法,但它们与过程密切相关。)您还应该注意一些其他事情:
- 将您的表达式放在大括号中(
expr {$a + $b}
而不是expr $a + $b
),因为这样可以实现更有效的编译策略。
- 仔细选择您的频道编码。(如果这样做
fconfigure $chan -translation binary
,该通道将传输字节而不是字符。但是,gets
在 8.4 中,在面向字节的通道上效率不是很高。使用-encoding iso8859-1 -translation lf
将提供大部分好处。)
- Tcl 很好地进行了通道缓冲。
- 可能值得用不同版本的 Tcl 对您的代码进行基准测试,看看哪个效果最好。如果您不想为了测试而安装多个 Tcl 解释器(次要)麻烦,请尝试使用tclkit构建进行测试。
进行面向行的转换的惯用方法是:
proc transformFile {sourceFile targetFile RE replacement} {
# Open for reading
set fin [open $sourceFile]
fconfigure $fin -encoding iso8859-1 -translation lf
# Open for writing
set fout [open $targetFile w]
fconfigure $fout -encoding iso8859-1 -translation lf
# Iterate over the lines, applying the replacement
while {[gets $fin line] >= 0} {
regsub -- $RE $line $replacement line
puts $fout $line
}
# All done
close $fin
close $fout
}
如果文件足够小,可以轻松放入内存中,则效率更高,因为整个匹配替换循环被提升到 C 级别:
proc transformFile {sourceFile targetFile RE replacement} {
# Open for reading
set fin [open $sourceFile]
fconfigure $fin -encoding iso8859-1 -translation lf
# Open for writing
set fout [open $targetFile w]
fconfigure $fout -encoding iso8859-1 -translation lf
# Apply the replacement over all lines
regsub -all -line -- $RE [read $fin] $replacement outputlines
puts $fout $outputlines
# All done
close $fin
close $fout
}
最后,正则表达式不一定是进行字符串匹配的最快方法(例如,string match
它要快得多,但接受更受限制的模式类型)。将一种样式的替换代码转换为另一种样式并让它真正快速运行并不是 100% 微不足道的(RE 非常灵活)。