以下给出几种优化Hypermesh二次开发tcl脚本的性能的方法。
注意:下面列出的时间是在一台奔腾266mhz的计算机上使用10000次迭代的Tcl命令运行时间。
合理的使用变量作用域
过程(proc)中定义的变量默认为局部变量。有许多方法可以访问过程作用范围之外的变量,包括使用命令global,upvar,uplevel和使用全局命名空间引用符::。
命令 | 时间消耗 |
---|---|
uplevel 含level | 每次迭代花费66微秒 |
uplevel | 每次迭代花费55微秒 |
upvar | 每次迭代花费55微秒 |
global | 每次迭代花费60微秒 |
全局命名空间引用符:: | 每次迭代花费55微秒 |
局部变量 | 每次迭代花费39微秒 |
整数变量加减
在整数加/减时,从变量中加上或减去一个值时,请使用incr
命令,而不要使用expr
调用。
命令 | 时间消耗 |
---|---|
expr | 每次迭代花费55微秒 |
incr: | 每次迭代花费11微秒 |
相差 | 5.0倍 |
括号表达式调用
使用expr
命令时,用**大括号{}**将表达式括起来,以利用字节码编译的优势。
方法 | 时间消耗 |
---|---|
不使用大括号 | 每次迭代花费143微秒 |
使用大括号 | 每次迭代花费55微秒 |
相差 | 2.60倍 |
proc返回值
尽可能避免在过程(proc)中使用return
函数。将变量设置为要返回的值,然后在过程底部(最后一行)调用set varname
会更有效。
命令 | 时间消耗 |
---|---|
return | 每次迭代花费39微秒 |
set | 每次迭代花费5微秒 |
相差 | 7.80倍 |
列表解析
解析列表的内容时,最快的方法是使用foreach
命令。其次是使用带有递减索引测试的while
循环,而效率最低的方法是使用for
循环。
命令 | 时间消耗 |
---|---|
for | 每次迭代花费159微秒 |
while | 每次迭代花费115微秒 |
foreach | 每次迭代花费66微秒 |
全局变量初始化
初始化全局变量时,请将它们放在过程(proc)中,然后在全局命名空间中访问它们以利用字节码编译的优势。
命令 | 时间消耗 |
---|---|
内联(inline)初始化 | 花费110000毫秒 |
proc中初始化 | 花费50000毫秒 |
数组与列表
对于大型列表搜索,使用数组可能更有效。列表搜索是顺序搜索,对于大型列表可能不是很有效。不用将项目添加到列表中,而是将数组的索引设置为项目名称。
- 使用列表
set a "1 2 3 4 5 6 7 8 9 0";
if {[lsearch $a 9] != -1} {
…command body…
}
- 使用数组
set a(1) 1;
set a(2) 2;
…
set a(9) 9;
set a(0) 0;
if {[info exist a(9)] == 1} {
…command body…
}
对于排序列表,根据列表类型,使用-sorted
选项以及-ascii,-decreasing,-dictionary,-inreasing,-integer
或-real
等参数可能更有效。
实例
以下示例显示了对全局列表中的数字的求和过程,并结合了上面讨论的一些性能优化方法。
set vals {10 20 30 40 50 60 70 80 90};
proc sum {} {
global vals;
set sum 0;
for { set i 0 } { $i < [ llength $vals ] } { incr i } {
set curVal [ lindex $vals $i ];
set sum [ expr $sum + $curVal ];
}
return $sum;
}
proc fasterSum {} {
set sum 0;
foreach val $::vals {
incr sum $val;
}
set sum;
}
sum过程函数花费: 829ms
fasterSum过程函数花费: 83ms
两者相差: 9.99倍
扫描下方二维码关注我的微信公众号 - CAE软件二次开发Lab,查看更多精彩文章!
