tcl中的文件写入操作需要很多时间

时间:2016-08-31 09:16:19

标签: tcl

set filePointer [open "fileName" "r"]
set fileWritePointer [open "fileNameWrite" "w"]
set lines [split [read $filePointer] "\n"]
close $filePointer
set length [llength $lines]
for {set i 0} {$i<$length} {incr i} {
        if {[regexp "Matching1" $line]} {
           puts $fileWritePointer $line
        }
        if {[regexp "Matching" $line]} {
           puts $fileWritePointer $line
        }
}
close $fileWritePointer

我一次读取文件的所有行并用新行字符拆分并在for循环中一次读取每一行。

使用regexp对行进行一些语法检查后,我使用以下语法将所选行转储到新文件中。

puts $filePointer $line

我的文件大约有200万行代码。 像这样,许多正则表达式匹配大约在1.5左右。

2 个答案:

答案 0 :(得分:1)

在不知道为什么代码很慢的情况下(或者您正在使用基线进行测量的情况),很难确定如何加速它。但是,您可以尝试切换到流处理:

set fin [open "fileName"]
set fout [open "fileNameWrite" "w"]
while {[gets $fin line] >= 0} {
    if {[regexp "Matching1" $line]} {
        puts $fout $line
    }
    if {[regexp "Matching" $line]} {
        puts $fout $line
    }
}
close $fout
close $fin

您应该确保正则表达式在处理期间是常量值,以避免为每一行重新编译它们(这些非常慢!)尽管这些常量值可以存储在变量中,只要这些变量在没有添加任何内容的情况下使用:

set RE1 "Matching1"
set RE2 "Matching"
# Note: these variables are NOT assigned to below! They are just used!

set fin [open "fileName"]
set fout [open "fileNameWrite" "w"]
while {[gets $fin line] >= 0} {
    # Added “--” to make sure that the REs are never interpreted as anything else
    if {[regexp -- $RE1 $line]} {
        puts $fout $line
    }
    if {[regexp -- $RE2 $line]} {
        puts $fout $line
    }
}
close $fout
close $fin

您也可以通过选择正确的编码,将所有这些代码放在一个程序等中来获得额外的速度。如上所述,很难确定在不知道代码为什么的情况下尝试的最佳方法是什么。实际上很慢,而这部分取决于运行它的系统。

答案 1 :(得分:0)

你真的需要正则表达式匹配吗?字符串匹配可能会更快。

可以针对同一行进行多个匹配,在这种情况下,您是否真的需要为每次匹配写入一次?如果没有,你可以通过跳过其余的匹配尝试来加快速度:

if {[regexp -- $RE1 $line]} {
    puts $fout $line
} elseif {[regexp -- $RE2 $line]} {
    puts $fout $line
} elseif { ... } {

if {
    [regexp -- $RE1 $line] ||
    [regexp -- $RE2 $line] ||
    ...
} then {
    puts $fout $line
}

switch -regexp -- $line \
    $RE1 - \
    $RE2 - \
    ...  - \
    default {
        puts $fout $line
    }