Tcl:测试空列表的最佳方法
Tcl: best way to test for empty list
抱歉,这是一个非常微不足道的问题,但它似乎微不足道,以至于我找不到任何建议:Tcl 中测试列表是否为空的最佳方法是什么?我会选择 if {$myList eq ""} ...
,或者有更好的方法吗?感谢您的帮助!
如果你知道你有一个列表(因为你已经这样做了或者正在使用其他处理值的操作),最好的空检查是寻找在它的 llength
处查看它是否为零。我通常更喜欢像这样使用结果,就好像它是布尔值一样,但是与零进行比较也很好。
if {[llength $theList]} {
puts "the list is NOT empty"
} else {
puts "the list IS empty"
}
是的,这会产生将值转换为列表的成本,但该转换缓存在值本身中(这是一种“内部表示”),因此下一个操作将其用作列表这样就快多了,因为它不需要重新解析任何东西。
我只想分享一些测试代码,它表明 if {$myList eq ""}...
比 if {![llength $myList}} ...
慢 很多 :
set repeats 10
foreach n {10 100 1000 10000 20000} {
puts "n = $n"
puts [time {
set l [list]
for {set i 0} {$i < $n} {incr i} {
lappend l $i
}
} $repeats]
puts [time {
set l [list]
for {set i 0} {$i < $n} {incr i} {
lappend l $i
if {![llength $l]} {
puts "empty (llength)"
}
}
} $repeats]
puts [time {
set l [list]
for {set i 0} {$i < $n} {incr i} {
lappend l $i
if {$l eq ""} {
puts "empty (eq)"
}
}
} $repeats]
}
这是输出;对于 n
的每个值:基线(不检查),检查 llength
,检查 eq
:
n = 10
5.0 microseconds per iteration
14.1 microseconds per iteration
14.0 microseconds per iteration
n = 100
40.6 microseconds per iteration
44.0 microseconds per iteration
105.8 microseconds per iteration
n = 1000
374.4 microseconds per iteration
440.7 microseconds per iteration
6240.1 microseconds per iteration
n = 10000
3534.4 microseconds per iteration
4485.8 microseconds per iteration
667206.0 microseconds per iteration
n = 20000
7576.7 microseconds per iteration
9051.9 microseconds per iteration
2761285.3 microseconds per iteration
我猜想使用 if {$l eq ""}...
的解决方案非常慢,因为每次检查完成时都会从列表转换为字符串。还是有不同的解释?
抱歉,这是一个非常微不足道的问题,但它似乎微不足道,以至于我找不到任何建议:Tcl 中测试列表是否为空的最佳方法是什么?我会选择 if {$myList eq ""} ...
,或者有更好的方法吗?感谢您的帮助!
如果你知道你有一个列表(因为你已经这样做了或者正在使用其他处理值的操作),最好的空检查是寻找在它的 llength
处查看它是否为零。我通常更喜欢像这样使用结果,就好像它是布尔值一样,但是与零进行比较也很好。
if {[llength $theList]} {
puts "the list is NOT empty"
} else {
puts "the list IS empty"
}
是的,这会产生将值转换为列表的成本,但该转换缓存在值本身中(这是一种“内部表示”),因此下一个操作将其用作列表这样就快多了,因为它不需要重新解析任何东西。
我只想分享一些测试代码,它表明 if {$myList eq ""}...
比 if {![llength $myList}} ...
慢 很多 :
set repeats 10
foreach n {10 100 1000 10000 20000} {
puts "n = $n"
puts [time {
set l [list]
for {set i 0} {$i < $n} {incr i} {
lappend l $i
}
} $repeats]
puts [time {
set l [list]
for {set i 0} {$i < $n} {incr i} {
lappend l $i
if {![llength $l]} {
puts "empty (llength)"
}
}
} $repeats]
puts [time {
set l [list]
for {set i 0} {$i < $n} {incr i} {
lappend l $i
if {$l eq ""} {
puts "empty (eq)"
}
}
} $repeats]
}
这是输出;对于 n
的每个值:基线(不检查),检查 llength
,检查 eq
:
n = 10
5.0 microseconds per iteration
14.1 microseconds per iteration
14.0 microseconds per iteration
n = 100
40.6 microseconds per iteration
44.0 microseconds per iteration
105.8 microseconds per iteration
n = 1000
374.4 microseconds per iteration
440.7 microseconds per iteration
6240.1 microseconds per iteration
n = 10000
3534.4 microseconds per iteration
4485.8 microseconds per iteration
667206.0 microseconds per iteration
n = 20000
7576.7 microseconds per iteration
9051.9 microseconds per iteration
2761285.3 microseconds per iteration
我猜想使用 if {$l eq ""}...
的解决方案非常慢,因为每次检查完成时都会从列表转换为字符串。还是有不同的解释?