TCL中的global和::有什么区别?
What is the difference between global and :: in TCL?
我正在使用 EDA 软件。它要求我依赖全局变量。
假设我有一个 proc,我正在寻找一个全局变量 CCK_FOO。我有两个选择:
- 在代码中使用
global CCK_FOO
。
- 使用
::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
请注意,上面的代码和下面的代码之间的时间不可比,因为它们执行的其他工作量不同。请查看 style1
和 style2
.
之间的时间差异
% 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
.
获得了相当多的加速
我正在使用 EDA 软件。它要求我依赖全局变量。 假设我有一个 proc,我正在寻找一个全局变量 CCK_FOO。我有两个选择:
- 在代码中使用
global CCK_FOO
。 - 使用
::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
请注意,上面的代码和下面的代码之间的时间不可比,因为它们执行的其他工作量不同。请查看 style1
和 style2
.
% 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
.