Golang 与 Java 的速度

我用 Java 写了一个程序,用 Go 写了一个等价的程序。我的 java 程序执行大约需要 5.95 秒,而 Go 程序大约需要 41.675789791 秒。虽然 Go 的速度与 C 或 C++ 相当,因为它像 C 一样编译,但为什么存在如此大的性能差异?程序如下:


围棋程序


package main



import (

    "math"

    "fmt"

    "time"

)


func main() {

    fmt.Printf("vvalue is %v", testFun(10, 16666611, 1000000000))

}


func fun(x float64) float64 {

    return math.Pow(x, 2) - x

}


func testFun(first float64, second float64, times int) float64 {

    var i = 0

    var result float64 = 0

    var dx float64

    dx = (second - first) / float64(times)

    for ; i < times; i++ {

        result += fun(first + float64(i) * dx)

    }

    return result * dx

}   

Java程序


public class Test {

public static void main(String[] args) {

    Test test = new Test();

    double re = test.testFun(10, 16666611, 1000000000);

    System.out.println(re);

}


private double testFun(double first, double second, long times) {

    int i = 0;

    double result = 0;

    double dx = (second - first) / times;

    for (; i < times; i++) {

        result += fun(first + i * dx);

    }

    return result * dx;

}


private double fun(double v) {

    return Math.pow(v, 2) - v;

}

}


青春有我
浏览 241回答 4
4回答

ITMISS

(根据上述答案的提示,我做了更多测试,并添加了一个C版本)在我的 linux 机器上,times =&nbsp;100000000。测试结果:当指数 =&nbsp;2.4&nbsp;Java:&nbsp;result:&nbsp;1.053906e+24,&nbsp;during:&nbsp;7432&nbsp;ms &nbsp;&nbsp;&nbsp;&nbsp;C:&nbsp;result:&nbsp;1.053906e+24,&nbsp;during:&nbsp;5544&nbsp;ms &nbsp;&nbsp;&nbsp;Go:&nbsp;result:&nbsp;1.053906e+24,&nbsp;during:&nbsp;8.716807708s当 exponent =&nbsp;2时,仍然使用pow()or&nbsp;Pow()。&nbsp;Java:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;630&nbsp;ms &nbsp;&nbsp;&nbsp;&nbsp;C:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;852&nbsp;ms &nbsp;&nbsp;&nbsp;Go:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;3.336549272s当 exponent =&nbsp;2时,而是使用x * x。&nbsp;Java:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;636&nbsp;ms &nbsp;&nbsp;&nbsp;&nbsp;C:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;340&nbsp;ms &nbsp;&nbsp;&nbsp;Go:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;115.491272ms概括:总的来说,go是真的快,根据上次的测试,比Java,甚至还要快C。但是,根据前 2 个测试,Java确实有一个很好的实现。pow()代码Test.java:/**&nbsp;* Compile:&nbsp;*&nbsp; javac Test.java&nbsp;* Run:&nbsp;*&nbsp; java Test&nbsp;*/&nbsp;public class Test {&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; Test test = new Test();&nbsp; &nbsp; long startAt = System.currentTimeMillis();&nbsp; &nbsp; &nbsp; &nbsp; double re = test.testFun(10, 16666611, 100000000);&nbsp; &nbsp; long during = System.currentTimeMillis() - startAt;&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("%10s: result: %e, during: %d ms\n", "Java", re, during);&nbsp; &nbsp; }&nbsp; &nbsp; private double testFun(double first, double second, long times) {&nbsp; &nbsp; &nbsp; &nbsp; int i = 0;&nbsp; &nbsp; &nbsp; &nbsp; double result = 0;&nbsp; &nbsp; &nbsp; &nbsp; double dx = (second - first) / times;&nbsp; &nbsp; &nbsp; &nbsp; for (; i < times; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += fun(first + i * dx);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return result * dx;&nbsp; &nbsp; }&nbsp; &nbsp; private double fun(double v) {&nbsp; &nbsp; &nbsp; &nbsp; return v * v - v;&nbsp; &nbsp; &nbsp; &nbsp; // return Math.pow(v, 2) - v;&nbsp; &nbsp; &nbsp; &nbsp; // return Math.pow(v, 2.4) - v;&nbsp; &nbsp; }}测试.c:/**&nbsp;* compile with:&nbsp;*&nbsp; gcc test.c -lm&nbsp;*/#include <math.h>#include <stdio.h>#include <stdlib.h>#include <sys/time.h>double fun(double v) {&nbsp; &nbsp; return v * v - v;&nbsp; &nbsp; // return pow(v, 2) - v;&nbsp; &nbsp; // return pow(v, 2.4) - v;}double testFun(double first, double second, long times) {&nbsp; &nbsp; int i;&nbsp; &nbsp; double result = 0;&nbsp; &nbsp; double dx = (second - first) / times;&nbsp; &nbsp; for (i = 0; i < times; i++) {&nbsp; &nbsp; &nbsp; &nbsp; result += fun(first + i * dx);&nbsp; &nbsp; }&nbsp; &nbsp; return result * dx;}long long current_timestamp() {&nbsp; &nbsp; struct timeval te;&nbsp; &nbsp; gettimeofday(&te, NULL); // get current time&nbsp; &nbsp; long long milliseconds =&nbsp; &nbsp; &nbsp; &nbsp; te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds&nbsp; &nbsp; // printf("milliseconds: %lld\n", milliseconds);&nbsp; &nbsp; return milliseconds;}int main(int argc, char *argv[]) {&nbsp; &nbsp; long long startAt = current_timestamp();&nbsp; &nbsp; double re = testFun(10, 16666611, 100000000);&nbsp; &nbsp; long long during = current_timestamp() - startAt;&nbsp; &nbsp; printf("%10s: result: %e, during: %lld ms\n", "C", re, during);&nbsp; &nbsp; return 0;}测试去:/**&nbsp;* How to run:&nbsp;*&nbsp; go run test.go&nbsp;*/package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "math"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; startAt := time.Now()&nbsp; &nbsp; result := testFun(10, 16666611, 100000000)&nbsp; &nbsp; during := time.Since(startAt)&nbsp; &nbsp; fmt.Printf("%10s: result: %e, during: %v\n", "Go", result, during)&nbsp; &nbsp; _ = math.Pow}func fun(x float64) float64 {&nbsp; &nbsp; return x*x - x&nbsp; &nbsp; // return math.Pow(x, 2) - x&nbsp; &nbsp; // return math.Pow(x, 2.4) - x}func testFun(first float64, second float64, times int) float64 {&nbsp; &nbsp; var i = 0&nbsp; &nbsp; var result float64 = 0&nbsp; &nbsp; var dx float64&nbsp; &nbsp; dx = (second - first) / float64(times)&nbsp; &nbsp; for ; i < times; i++ {&nbsp; &nbsp; &nbsp; &nbsp; result += fun(first + float64(i)*dx)&nbsp; &nbsp; }&nbsp; &nbsp; return result * dx}编译:javac&nbsp;Test.java;&nbsp;gcc&nbsp;test.c&nbsp;-lm;&nbsp;go&nbsp;build&nbsp;test.go跑步:java&nbsp;Test;&nbsp;./a.out&nbsp;;&nbsp;./test@Update - 带有-O2或-O3选项的 C 程序正如Raffaello评论中所建议的那样,在编译C程序时,可以使用-O2或-O3进一步优化程序。并且,以下是程序的测试结果C:当指数 =&nbsp;2.4时。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;5805&nbsp;ms &nbsp;C&nbsp;with&nbsp;`-O2`:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;5324&nbsp;ms &nbsp;C&nbsp;with&nbsp;`-O3`:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;5326&nbsp;ms当 exponent =&nbsp;2时,仍然使用pow()or&nbsp;Pow()。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;897&nbsp;ms &nbsp;C&nbsp;with&nbsp;`-O2`:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;119&nbsp;ms &nbsp;C&nbsp;with&nbsp;`-O3`:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;121&nbsp;ms当 exponent =&nbsp;2时,而是使用x * x。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;353&nbsp;ms &nbsp;C&nbsp;with&nbsp;`-O2`:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;122&nbsp;ms &nbsp;C&nbsp;with&nbsp;`-O3`:&nbsp;result:&nbsp;1.543194e+21,&nbsp;during:&nbsp;119&nbsp;ms摘要-(-O2和-O3选项):有-O2和-O3选项当 base 是整数(例如 2)时,将使 c 程序更快,快几倍。当 base 是浮点数(例如 2.4)时,它也更快,但非常小。比较-O2和-O3,它们在上述测试中非常接近。

手掌心

不要从另一种语言翻译。在 Go 中编写程序的 Go 版本。例如x*x - x,package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "math"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; start := time.Now()&nbsp; &nbsp; v := testFun(10, 16666611, 1000000000)&nbsp; &nbsp; since := time.Since(start)&nbsp; &nbsp; fmt.Printf("value is %v\ntime is %v\n", v, since)}func fun(x float64) float64 {&nbsp; &nbsp; return x*x - x}func testFun(first float64, second float64, times int) float64 {&nbsp; &nbsp; sum := float64(0)&nbsp; &nbsp; dx := (second - first) / float64(times)&nbsp; &nbsp; for i := 0; i < times; i++ {&nbsp; &nbsp; &nbsp; &nbsp; sum += fun(first + float64(i)*dx)&nbsp; &nbsp; }&nbsp; &nbsp; return sum * dx}输出:$ go versiongo version devel +5c11480631 Fri Aug 10 20:02:31 2018 +0000 linux/amd64$ go run speed.govalue is 1.543194272428967e+21time is 1.011965238s$你得到什么结果?

子衿沉夜

我建议math.Pow(x,y)在 Go 中实际上没有对whilex^y的整数值进行任何优化,而只是为。至少在两个程序中用简单替换时,Java 的时间为 6.5 秒,而 Go 的时间为 1.4 秒。使用代替我仍然得到 6.5 秒的 Java 而 29.4 秒的围棋。yMath.pow(x,y)x*xy==2powx*xpow

犯罪嫌疑人X

从理论上讲,Go 在开始时需要时间来编译所有源代码,因此它的启动时间会很慢,但是当它完成启动并一条一条地执行命令时,它会运行得很快。执行时间可以与 C/C++ 进行比较。你不能仅仅在几行代码中比较它们,你会发现启动时间在千文件程序中会受到很大影响。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go