Go 运行性能

Go 运行性能,go,Go,考虑以下基准: package main import ( "io/ioutil" "os" "os/exec" "testing" ) func BenchmarkRun(b *testing.B) { for i := 0; i < b.N; i++ { source := `package main import "fmt" func main() { fmt.Println("foo") }`

考虑以下基准:

package main

import (
    "io/ioutil"
    "os"
    "os/exec"
    "testing"
)

func BenchmarkRun(b *testing.B) {
    for i := 0; i < b.N; i++ {
        source := `package main

import "fmt"

func main() {
    fmt.Println("foo")
}`
        if err := ioutil.WriteFile("cmd.go", []byte(source), 0777); err != nil {
            b.Error(err)
        }
        defer os.Remove("cmd.go")

        if err := exec.Command("go", "run", "cmd.go").Run(); err != nil {
            b.Error(err)
        }
    }
}
主程序包
进口(
“io/ioutil”
“操作系统”
“os/exec”
“测试”
)
func BenchmarkRun(b*testing.b){
对于i:=0;i
每次操作大约需要0.3秒

有没有办法加快编译/运行周期


编写临时文件并运行exec似乎很笨拙。有没有办法不用这样做就调用编译器?

您可以创建一个二进制文件,以后再使用它。 例如:

主程序包
进口(
“io/ioutil”
“操作系统”
“os/exec”
“路径”
“测试”
)
func BenchmarkRun(b*testing.b){
tmpdir,err:=ioutil.TempDir(“,“go bench-”)
如果错误!=零{
b、 致命的(错误)
}
延迟os.RemoveAll(tmpdir)
来源:=`包主
输入“fmt”
func main(){
fmt.Println(“foo”)
}`
如果err:=ioutil.WriteFile(path.Join(tmpdir,“cmd.go”),[]字节(源代码),0777);err!=nil{
b、 致命的(错误)
}
延迟os.Remove(path.Join(tmpdir,“cmd.go”))
cmd:=exec.Command(“go”,“build”,“-o”,“cmd”,“Command”)
cmd.Dir=tmpdir
如果错误:=cmd.Run();错误!=nil{
b、 致命的(错误)
}
延迟os.Remove(path.Join(tmpdir,“cmd”))
b、 重置计时器()
对于i:=0;i
No。编译器依赖文件进行输入,但您可以直接调用编译器,尽管我怀疑保存创建临时目录的两个
mkdir
调用是否会节省大量时间。
package main

import (
        "io/ioutil"
        "os"
        "os/exec"
        "path"
        "testing"
)

func BenchmarkRun(b *testing.B) {
        tmpdir, err := ioutil.TempDir("", "go-bench-")
        if err != nil {
                b.Fatal(err)
        }
        defer os.RemoveAll(tmpdir)

        source := `package main

import "fmt"

func main() {
    fmt.Println("foo")
}`
        if err := ioutil.WriteFile(path.Join(tmpdir, "cmd.go"), []byte(source), 0777); err != nil {
                b.Fatal(err)
        }
        defer os.Remove(path.Join(tmpdir, "cmd.go"))

        cmd := exec.Command("go", "build", "-o", "cmd", ".")
        cmd.Dir = tmpdir
        if err := cmd.Run(); err != nil {
                b.Fatal(err)
        }
        defer os.Remove(path.Join(tmpdir, "cmd"))

        b.ResetTimer()
        for i := 0; i < b.N; i++ {
                if err := exec.Command(path.Join(tmpdir, "cmd")).Run(); err != nil {
                        b.Error(err)
                }
        }
}