英文:
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 (
	"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)
		}
	}
}
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 (
        "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)
                }
        }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论