TCL 全局变量 vs 双冒号变量

TCL global variable vs double colon variable

在TCL代码中有什么区别:

global MyVar
set MyVar 5

和代码

set ::MyVar 5 

? 据我所知 ::MyVar 意味着 MyVar 将是一个全局变量。那么区别是什么呢?

如果这是在过程中,则设置什么变量或将什么值放入其中没有功能上的区别。 (global 在过程之外没有效果,以及其他具有局部变量 table 的东西,例如 lambda 和方法。)

真正的区别在于事情的完成方式。特别是,global 设置一次,以便将来的非限定变量访问很快,而使用限定形式 always 进行完整查找(可能涉及多个散列 table 访问)。效果是这样的,虽然使用完全限定形式的单次读取或写入速度更快,但如果使用 global 完成多次访问总是更快(并且 global 调用中的多个变量效果会更强一些,因为有些成本是可以摊销的)。

但是不要相信我的话。用time做一些示例程序自己测试一下,大概是这样的:

proc write1 {} {
    global MyVar
    set MyVar 5
    return
}
proc write2 {} {
    global MyVar
    set MyVar 5
    set MyVar 5
    return
}
proc write3 {} {
    global MyVar MyOtherVar
    set MyVar 5
    set MyOtherVar 5
    return
}
proc write4 {} {
    global MyVar MyOtherVar
    set MyVar 5
    set MyOtherVar 5
    set MyVar 5
    set MyOtherVar 5
    return
}
proc write5 {} {
    set ::MyVar 5
    return
}
proc write6 {} {
    set ::MyVar 5
    set ::MyVar 5
    return
}
proc write7 {} {
    set ::MyVar 5
    set ::MyOtherVar 5
    return
}
proc write8 {} {
    set ::MyVar 5
    set ::MyOtherVar 5
    set ::MyVar 5
    set ::MyOtherVar 5
    return
}

foreach cmd {write1 write2 write3 write4 write5 write6 write7 write8} {
    # Execute once to ensure everything is internally optimised
    $cmd
    # Now the timing run
    puts "$cmd : [time { $cmd } 100000]"
}

在我的笔记本电脑上(现在已经有好几年了)运行 Tcl 8.6.9,我明白了:

write1 : 0.62610808 microseconds per iteration
write2 : 0.63969525 microseconds per iteration
write3 : 0.73437284 microseconds per iteration
write4 : 0.7519245699999999 microseconds per iteration
write5 : 0.62230006 microseconds per iteration
write6 : 0.8437912799999999 microseconds per iteration
write7 : 0.8246234299999999 microseconds per iteration
write8 : 1.2297289900000001 microseconds per iteration

如您所见(并在您自己的硬件上自己确认),write1write5 慢,但对于其他每个对,使用 global 是一个性能取胜。 (我有点惊讶 write3 胜过 write7,但数字不会说谎。)