TCL中的global和::有什么区别?

What is the difference between global and :: in TCL?

我正在使用 EDA 软件。它要求我依赖全局变量。 假设我有一个 proc,我正在寻找一个全局变量 CCK_FOO。我有两个选择:

  1. 在代码中使用 global CCK_FOO
  2. 使用::CCK_FOO

在 "management level" 方面,它们看起来完全相同。这两种方法是否有 "under the hood" 优缺点?我实际上更喜欢使用 ::,因为它可以最大限度地减少意外覆盖的可能性。

在引擎盖下,使用 ::CCK_FOO 每次执行引擎使用它时都会经过解析的变量名路由,而 global CCK_FOO 允许引擎设置一个局部变量(使用局部变量table — LVT — 插槽) linked 到全局变量。通过 LVT 访问要快得多,因为它只是一个 C 数组的索引(还有一个额外的指针取消引用,因为它是 link),而查找全局变量意味着进行散列 table 查找(有一个hash table 用于全局命名空间实现中的变量)。 ::CCK_FOO::CCK_FOO 的实际内部解析被缓存。

实际上,如果您只访问一个变量一次,那么使用 ::CCK_FOO 可能 稍微 更快,但是一旦您使用它两次(更不用说更多)您可以通过支付 global CCK_FOO 的额外费用并通过 LVT 索引访问它来获得更好的性能。

% proc style1 {} {
    set ::CCK_FOO abc
}
% proc style2 {} {
    global CCK_FOO
    set CCK_FOO abc
}
% time { style1 } 100000
0.52350635 microseconds per iteration
% time { style2 } 100000
0.5267007100000001 microseconds per iteration

请注意,上面的代码和下面的代码之间的时间不可比,因为它们执行的其他工作量不同。请查看 style1style2.

之间的时间差异
% proc style1 {} {
    set ::CCK_FOO [string reverse $::CCK_FOO]
}
% proc style2 {} {
    global CCK_FOO
    set CCK_FOO [string reverse $CCK_FOO]
}
% time { style1 } 100000
0.9733970200000001 microseconds per iteration
% time { style2 } 100000
0.78782093 microseconds per iteration
# Calibration...
% time { string reverse abc } 100000
0.28694849 microseconds per iteration

如您所见,只需两次访问, 我们通过使用 global.

获得了相当多的加速