如何让proc更有效? [英] How make proc more effective?

查看:60
本文介绍了如何让proc更有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个顶点集合:[ x1 y1 x2 y2 .. xn yn ]

There is a collection of vertices: [ x1 y1 x2 y2 .. xn yn ]

我想更改这些坐标的中心.所以我尝试:

I would like to change the center of those coordinates. So I try:

proc changeCenter { vertices X Y } {
    set myList [list]
    foreach element $vertices {
        lappend myList [expr [lindex $element 0] + $X]
        lappend myList [expr [lindex $element 1] + $Y]
    }

 return $myList 
}

但是它的性能太慢了.

如何更改上述代码以使其更有效,或者可能需要更改顶点的表示?

How can I change above code to be more effective or maybe need to change the representation of vertices?

推荐答案

你的 changeCenter proc 表明顶点集合是一个对列表 ({{x1 y1} {x2 y2} ...}),但您返回的是一个平面列表:

Your changeCenter proc indicates the vertices collection is a list of pairs ({{x1 y1} {x2 y2} ...}), yet you are returning a flat list:

proc changeCenter { vertices deltaX deltaY } {
    set recentered [list]
    foreach vertex $vertices {
        lassign $vertex x y
        lappend recentered [list [expr {$x + $deltaX}] [expr {$y + $deltaY}]]
    }
    return $recentered 
}

如果顶点确实是一个平面列表({x1 y1 x2 y2 ...}),则一次读取列表 2 个元素:

If the vertices really are a flat list ({x1 y1 x2 y2 ...}) then read the list 2 elements at a time:

proc changeCenter { vertices deltaX deltaY } {
    set recentered [list]
    foreach {x y} $vertices {
        lappend recentered [expr {$x + $deltaX}] [expr {$y + $deltaY}]
    }
    return $recentered 
}

<小时>

我没有对其进行基准测试,但我怀疑就地更新顶点列表可能比附加到新列表更快:


I haven't benchmarked it, but I suspect updating the vertices list in-place might be faster than appending to a new list:

proc changeCenter { vertices deltaX deltaY } {
    for {set i 0} {$i < [llength $vertices]} {incr i} {
        lset vertices $i 0 [expr {[lindex $vertices $i 0] + $deltaX}] 
        lset vertices $i 1 [expr {[lindex $vertices $i 1] + $deltaY}] 
    }
    return $vertices 
}

proc changeCenter { vertices deltaX deltaY } {
    for {set i 0} {$i < [llength $vertices]} {incr i 2} {
        lset vertices $i [expr {[lindex $vertices $i] + $deltaX}] 
        set j [expr {$i + 1}]
        lset vertices $j [expr {[lindex $vertices $j] + $deltaY}] 
    }
    return $vertices
}

取决于上面提到的顶点列表的结构.

depending on the structure of the vertices list as mentioned above.

按名称传递顶点列表会更快(避免复制数据):

Passing the vertices list by name would be faster still (avoid copying the data):

proc changeCenter { verticesName deltaX deltaY } {
    upvar 1 $verticesName v
    for {set i 0} {$i < [llength $v]} {incr i 2} {
        lset v $i [expr {[lindex $v $i] + $deltaX}] 
        set j [expr {$i + 1}]
        lset v $j [expr {[lindex $v $j] + $deltaY}] 
    }
    # no need to return a value
}

并用变量name调用它:

changeCenter vertices 1 2

这篇关于如何让proc更有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆