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 ""}... 的解决方案非常慢,因为每次检查完成时都会从列表转换为字符串。还是有不同的解释?