在哪个片段分配较少的对象?或者他们都使用相同数量的分配,如果是的话;为什么? (:常量在Go中如何工作?
for i := 0; i < 10000000; i++ {
log.println("hello")
}
请问下面的代码仅分配1串
const (
HELLO string = "hello"
)
for i := 0; i < 10000000; i++ {
log.println(HELLO)
}
在哪个片段分配较少的对象?或者他们都使用相同数量的分配,如果是的话;为什么? (:常量在Go中如何工作?
for i := 0; i < 10000000; i++ {
log.println("hello")
}
请问下面的代码仅分配1串
const (
HELLO string = "hello"
)
for i := 0; i < 10000000; i++ {
log.println(HELLO)
}
这是你的程序的适应打印出在这两种情况下的基本字符串表示
package main
import (
"fmt"
"reflect"
"unsafe"
)
const (
Hello string = "hello"
)
func main() {
for i := 0; i < 3; i++ {
a := "hello"
sh := (*reflect.StringHeader)(unsafe.Pointer(&a))
fmt.Println(a, " ", *sh)
}
fmt.Println()
for i := 0; i < 3; i++ {
a := Hello
sh := (*reflect.StringHeader)(unsafe.Pointer(&a))
fmt.Println(a, " ", *sh)
}
}
这里的?输出:
hello {4870353 5}
hello {4870353 5}
hello {4870353 5}
hello {4870353 5}
hello {4870353 5}
hello {4870353 5}
输出中的{}
中的字符串标题显示了指向字符数据(“hello”)的指针和字符串的长度。
您可以看到指向字符串数据的指针在整个程序中都是相同的:字节数据“hello”恰好在一个内存地址(此处为4870353)处引用,无论循环次数如何,无论它是一个硬编码的字符串或常量。
语言规范本身并不保证这种行为,但常量字符串实习是一种自然优化,如果以任何显着不同的方式行事,那将是令人惊讶的。
寻找Go是否进行一些分配的最简单方法是编写基准。在你的情况的代码可能看起来像:
package sof
import "log"
const (
HELLO = "hello"
)
func forString(max int) {
for i := 0; i < max; i++ {
logMsg("hello", false)
}
}
func forConst(max int) {
for i := 0; i < max; i++ {
logMsg(HELLO, false)
}
}
func logMsg(msg string, stdOut bool) {
if stdOut {
log.Println(msg)
}
}
和Benchmark:
package sof
import "testing"
func BenchmarkForString(b *testing.B) {
for i := 0; i < b.N; i++ {
forString(i)
}
}
func BenchmarkForConst(b *testing.B) {
for i := 0; i < b.N; i++ {
forConst(i)
}
}
然后,你可以运行基准:
go test -bench=. -benchmem
很重要的是-benchmem标志。如果没有它,你的基准测试只会告诉你关于基准时间的信息 - 你不会得到关于每个操作的分配数量和平均分配大小的信息。
输出的基准:
testing: warning: no tests to run
BenchmarkForString-4 100000 133551 ns/op 0 B/op 0 allocs/op
BenchmarkForConst-4 100000 128585 ns/op 0 B/op 0 allocs/op
PASS
ok .../sof 26.475s
在您对分配的大小和其编号的信息最后2列。在你的例子中只有零,这意味着这两个funcs不作任何分配:)
我很确定编译器将内联字符串,而不是分配它X次。如果一种语言做到了,我就不会使用它。 – squiguy
将两个示例的程序集输出与'go tool compile -S' –