去lang字符串常量

Rob*_*US2 5 benchmarking go

内联字符串和Go中使用的常量字符串之间是否有区别,或者这是否完全由编译器优化?

具有100B迭代的示例基准代码:

package main

import "fmt"
import "time"
import "log"

func main() {
    // String
    start := time.Now()
    for i := 0; i < 100000000; i++ {
        x := "My String"
        if i % 1000000 == 0{
            fmt.Printf(x)
        }
    }
    elapsed := time.Since(start)
    log.Printf("\nTook %s", elapsed)

    // Constant
    start2 := time.Now()
    const MY_STRING = "My String 2"
    for i := 0; i < 100000000; i++ {
        x := MY_STRING
        if i % 1000000 == 0 {
            fmt.Printf(x)
        }
    }

    elapsed2 := time.Since(start2)
    log.Printf("\nTook %s", elapsed2)

    // Proof that the timer does work :)
    start3 := time.Now()
    time.Sleep(100 * time.Millisecond)
    elapsed3 := time.Since(start3)
    log.Printf("\nTook %s", elapsed3)

}
Run Code Online (Sandbox Code Playgroud)

输出:

My StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy StringMy String2009/11/10 23:00:00 
Took 0
My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 2My String 22009/11/10 23:00:00 
Took 0
2009/11/10 23:00:00 
Took 100ms

Program exited.
Run Code Online (Sandbox Code Playgroud)

Jam*_*dge 9

两者之间的编译代码没有区别,因此不应影响您的结果.以下示例文件:

package foo

func foo() string {
    x := "Foo"
    return x
}

const MY_STRING = "Bar"

func bar() string {
    x := MY_STRING
    return x
}
Run Code Online (Sandbox Code Playgroud)

汇编器输出显示两个函数是相同的(以不同的字符串常量为模):

$ go tool 6g -S foo.go

--- prog list "foo" ---
0000 (foo.go:3) TEXT    foo+0(SB),$0-16
0001 (foo.go:3) FUNCDATA $0,gcargs·0+0(SB)
0002 (foo.go:3) FUNCDATA $1,gclocals·0+0(SB)
0003 (foo.go:3) TYPE    ~anon0+0(FP){string},$16
0004 (foo.go:4) LEAQ    go.string."Foo"+0(SB),BX
0005 (foo.go:4) MOVQ    (BX),CX
0006 (foo.go:4) MOVQ    8(BX),BP
0007 (foo.go:5) MOVQ    CX,~anon0+0(FP)
0008 (foo.go:5) MOVQ    BP,~anon0+8(FP)
0009 (foo.go:5) RET     ,

--- prog list "bar" ---
0010 (foo.go:10) TEXT    bar+0(SB),$0-16
0011 (foo.go:10) FUNCDATA $0,gcargs·1+0(SB)
0012 (foo.go:10) FUNCDATA $1,gclocals·1+0(SB)
0013 (foo.go:10) TYPE    ~anon0+0(FP){string},$16
0014 (foo.go:11) LEAQ    go.string."Bar"+0(SB),BX
0015 (foo.go:11) MOVQ    (BX),CX
0016 (foo.go:11) MOVQ    8(BX),BP
0017 (foo.go:12) MOVQ    CX,~anon0+0(FP)
0018 (foo.go:12) MOVQ    BP,~anon0+8(FP)
0019 (foo.go:12) RET     ,
Run Code Online (Sandbox Code Playgroud)

如您所见,在两种情况下,字符串常量都以相同的方式加载.