Go运行性能

huangapple go评论79阅读模式
英文:

Go run performance

问题

考虑以下基准测试代码:

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)
		}
	}
}

每个操作大约需要0.3秒。

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

写一个临时文件并执行"go run"看起来有些笨拙。有没有一种方法可以在不这样做的情况下调用编译器?

英文:

Consider the following benchmark:

package main

import (
	&quot;io/ioutil&quot;
	&quot;os&quot;
	&quot;os/exec&quot;
	&quot;testing&quot;
)

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

import &quot;fmt&quot;

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

		if err := exec.Command(&quot;go&quot;, &quot;run&quot;, &quot;cmd.go&quot;).Run(); err != nil {
			b.Error(err)
		}
	}
}

This takes around 0.3sec per operation.

Is there any way of speeding up a compile / run cycle?

It seems clumsy to write a temporary file and exec go run. Is there a way to invoke the compiler without doing this?

答案1

得分: 1

你可以随时创建一个二进制文件,并在以后使用它。

示例:

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)
		}
	}
}
英文:

You can always create a binary and use it later on.
Example:

package main

import (
        &quot;io/ioutil&quot;
        &quot;os&quot;
        &quot;os/exec&quot;
        &quot;path&quot;
        &quot;testing&quot;
)

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

        source := `package main

import &quot;fmt&quot;

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

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

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

huangapple
  • 本文由 发表于 2015年6月20日 03:09:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/30945605.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定