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