Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在go1.4中,是否有必要放弃堆栈上过大的变量以避免堆栈复制?_Go - Fatal编程技术网

在go1.4中,是否有必要放弃堆栈上过大的变量以避免堆栈复制?

在go1.4中,是否有必要放弃堆栈上过大的变量以避免堆栈复制?,go,Go,正如我们所知,goroutine的堆栈可以通过在go1.4中复制堆栈来增加。我的问题是,在go中是否有必要避免堆栈上的局部变量过大? 比如说 func foo(){ var buf [8096]int //do something with buf } 或 我的意思是,是否有必要使用后一个示例来避免由于堆栈复制而导致的大变量?堆栈几乎总是比堆快。在哪里定义变量更多的是关于范围。由于在后一个示例中Go是词汇范围的语言,所以会弄脏全局名称空间,使var buf在程序中的任何地方都可见。

正如我们所知,goroutine的堆栈可以通过在go1.4中复制堆栈来增加。我的问题是,在go中是否有必要避免堆栈上的局部变量过大? 比如说

func foo(){
   var buf [8096]int
   //do something with buf
}


我的意思是,是否有必要使用后一个示例来避免由于堆栈复制而导致的大变量?

堆栈几乎总是比堆快。在哪里定义变量更多的是关于范围。由于在后一个示例中Go是词汇范围的语言,所以会弄脏全局名称空间,使var buf在程序中的任何地方都可见。这是语义上的差异。所以你最好做一些语义正确的事情

如果不想在堆栈中重新分配另一个大对象,则应使用指针而不是全局变量。对于go1.4,本规范适用于:

package main

import "fmt"

func do(v *[3]int) {
    v[1] = 99
}

func main() {
    var r [3]int
    do(&r)
    fmt.Println(r)
    //Prints [0 99 0]
}
如果不使用指针,这将失败,因为数组是作为值而不是引用传递的:

package main

import "fmt"

func do(v [3]int) {
    v[1] = 99
}

func main() {
    var r [3]int
    do(r)
    fmt.Println(r)
    //Prints [0 0 0]
}

注意:这不适用于切片;切片始终作为引用传递。

您能否发布一个真实的示例,说明由于堆栈拆分而导致的性能不佳?抽象地回答这个问题是不可能的,因为要获得高效的代码,你需要分析。仅仅因为函数体中有一些东西并不意味着它在堆栈上。好吧,Go的编译器有时会在堆上任意分配非常大的局部变量,即使它们出于性能原因没有逃逸。
package main

import "fmt"

func do(v [3]int) {
    v[1] = 99
}

func main() {
    var r [3]int
    do(r)
    fmt.Println(r)
    //Prints [0 0 0]
}