Golang 与 Java 的速度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51806224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Speed of Golang Vs Java
提问by ankur agrawal
I have written a program in Java and equivalent in Go. My java program is taking around 5.95 seconds to execute while Go program is taking around 41.675789791 seconds. While speed of Go is comparable to C or C++ as it is compiled like C then Why this much of performance difference exists? Programs are as follows:
我用 Java 编写了一个程序,用 Go 编写了一个等效的程序。我的 Java 程序执行时间约为 5.95 秒,而 Go 程序执行时间约为 41.675789791 秒。虽然 Go 的速度与 C 或 C++ 相当,因为它像 C 一样编译,但为什么会存在如此大的性能差异?程序如下:
Go Program
围棋程序
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 Program
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;
}
}
回答by peterSO
Don't translate from another language. Write the Go version of your program in Go. For example, x*x - x
,
不要从其他语言翻译。用 Go 编写程序的 Go 版本。例如x*x - x
,
package main
import (
"fmt"
"math"
"time"
)
func main() {
start := time.Now()
v := testFun(10, 16666611, 1000000000)
since := time.Since(start)
fmt.Printf("value is %v\ntime is %v\n", v, since)
}
func fun(x float64) float64 {
return x*x - x
}
func testFun(first float64, second float64, times int) float64 {
sum := float64(0)
dx := (second - first) / float64(times)
for i := 0; i < times; i++ {
sum += fun(first + float64(i)*dx)
}
return sum * dx
}
Output:
输出:
$ go version
go version devel +5c11480631 Fri Aug 10 20:02:31 2018 +0000 linux/amd64
$ go run speed.go
value is 1.543194272428967e+21
time is 1.011965238s
$
What results do you get?
你得到什么结果?
回答by Steffen Ullrich
I would suggest that math.Pow(x,y)
in Go actually does x^y
without any optimization for integer values of y
while Math.pow(x,y)
simply does x*x
for y==2
. At least when replacing pow
with a simple x*x
in both programs I get 6.5 seconds for Java vs. 1.4 seconds for Go. Using pow
instead I still get 6.5 seconds for Java while 29.4 seconds for Go.
我建议math.Pow(x,y)
在 Go 中实际上没有x^y
对y
while 的整数值进行任何优化,而Math.pow(x,y)
只是x*x
for y==2
。至少在两个程序pow
中用 simple替换时x*x
,Java 为 6.5 秒,而 Go 为 1.4 秒。使用pow
代替我仍然得到6.5秒为Java而29.4秒了围棋。
回答by Eric Wang
(With tips from above answers, I did more test, with an additional C
version)
(根据上述答案的提示,我做了更多的测试,还有一个额外的C
版本)
On my linux machine, with times = 100000000.
在我的 linux 机器上, times = 100000000。
Testing result:
测试结果:
- When exponent = 2.4
- 当指数 = 2.4
Java: result: 1.053906e+24, during: 7432 ms C: result: 1.053906e+24, during: 5544 ms Go: result: 1.053906e+24, during: 8.716807708s
Java: result: 1.053906e+24, during: 7432 ms C: result: 1.053906e+24, during: 5544 ms Go: result: 1.053906e+24, during: 8.716807708s
- When exponent = 2, still use
pow()
orPow()
.
- 当 exponent = 2 时,仍使用
pow()
orPow()
。
Java: result: 1.543194e+21, during: 630 ms C: result: 1.543194e+21, during: 852 ms Go: result: 1.543194e+21, during: 3.336549272s
Java: result: 1.543194e+21, during: 630 ms C: result: 1.543194e+21, during: 852 ms Go: result: 1.543194e+21, during: 3.336549272s
- When exponent = 2, but use
x * x
instead.
- 当 exponent = 2 时,
x * x
改为使用。
Java: result: 1.543194e+21, during: 636 ms C: result: 1.543194e+21, during: 340 ms Go: result: 1.543194e+21, during: 115.491272ms
Java: result: 1.543194e+21, during: 636 ms C: result: 1.543194e+21, during: 340 ms Go: result: 1.543194e+21, during: 115.491272ms
Summary:
概括:
- In general,
go
is really fast, according to the last test, faster thanJava
, or evenC
. - But,
Java
really have a goodpow()
implementation, according to the first 2 test.
- 一般来说,
go
真的很快,根据上次测试,比Java
,甚至C
。 - 但是,根据前 2 项测试,
Java
确实有一个很好的pow()
实现。
Code
代码
Test.java:
测试.java:
/**
* Compile:
* javac Test.java
* Run:
* java Test
*/
public class Test {
public static void main(String[] args) {
Test test = new Test();
long startAt = System.currentTimeMillis();
double re = test.testFun(10, 16666611, 100000000);
long during = System.currentTimeMillis() - startAt;
System.out.printf("%10s: result: %e, during: %d ms\n", "Java", re, during);
}
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 v * v - v;
// return Math.pow(v, 2) - v;
// return Math.pow(v, 2.4) - v;
}
}
test.c:
测试.c:
/**
* compile with:
* gcc test.c -lm
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
double fun(double v) {
return v * v - v;
// return pow(v, 2) - v;
// return pow(v, 2.4) - v;
}
double testFun(double first, double second, long times) {
int i;
double result = 0;
double dx = (second - first) / times;
for (i = 0; i < times; i++) {
result += fun(first + i * dx);
}
return result * dx;
}
long long current_timestamp() {
struct timeval te;
gettimeofday(&te, NULL); // get current time
long long milliseconds =
te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds
// printf("milliseconds: %lld\n", milliseconds);
return milliseconds;
}
int main(int argc, char *argv[]) {
long long startAt = current_timestamp();
double re = testFun(10, 16666611, 100000000);
long long during = current_timestamp() - startAt;
printf("%10s: result: %e, during: %lld ms\n", "C", re, during);
return 0;
}
test.go:
测试去:
/**
* How to run:
* go run test.go
*/
package main
import (
"fmt"
"math"
"time"
)
func main() {
startAt := time.Now()
result := testFun(10, 16666611, 100000000)
during := time.Since(startAt)
fmt.Printf("%10s: result: %e, during: %v\n", "Go", result, during)
_ = math.Pow
}
func fun(x float64) float64 {
return x*x - x
// return math.Pow(x, 2) - x
// return math.Pow(x, 2.4) - 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
}
Compile:
编译:
javac Test.java; gcc test.c -lm; go build test.go
Run:
跑:
java Test; ./a.out ; ./test
@Update - C program with -O2
or -O3
option
@Update - 带有-O2
或-O3
选项的C 程序
As suggested by Raffaello
in the comment, when compiling C program, could use -O2
or -O3
to further optimize the program.
正如Raffaello
评论中所建议的,在编译 C 程序时,可以使用-O2
或-O3
进一步优化程序。
And, following are the test result for C
program:
并且,以下是C
程序的测试结果:
- When exponent = 2.4.
- 当指数 = 2.4 时。
C: result: 1.543194e+21, during: 5805 ms C with `-O2`: result: 1.543194e+21, during: 5324 ms C with `-O3`: result: 1.543194e+21, during: 5326 ms
C: result: 1.543194e+21, during: 5805 ms C with `-O2`: result: 1.543194e+21, during: 5324 ms C with `-O3`: result: 1.543194e+21, during: 5326 ms
- When exponent = 2, still use
pow()
orPow()
.
- 当 exponent = 2 时,仍使用
pow()
orPow()
。
C: result: 1.543194e+21, during: 897 ms C with `-O2`: result: 1.543194e+21, during: 119 ms C with `-O3`: result: 1.543194e+21, during: 121 ms
C: result: 1.543194e+21, during: 897 ms C with `-O2`: result: 1.543194e+21, during: 119 ms C with `-O3`: result: 1.543194e+21, during: 121 ms
- When exponent = 2, but use
x * x
instead.
- 当 exponent = 2 时,
x * x
改为使用。
C: result: 1.543194e+21, during: 353 ms C with `-O2`: result: 1.543194e+21, during: 122 ms C with `-O3`: result: 1.543194e+21, during: 119 ms
C: result: 1.543194e+21, during: 353 ms C with `-O2`: result: 1.543194e+21, during: 122 ms C with `-O3`: result: 1.543194e+21, during: 119 ms
Summary- (-O2
and -O3
option):
摘要- (-O2
和-O3
选项):
- With
-O2
and-O3
option- When base is integer (e.g 2), would make c program quicker, by several times.
- When base is floating point number (e.g 2.4), it's also quicker, but very minimal.
- Comparing between
-O2
and-O3
, they are quite close in above tests.
- 有
-O2
和-O3
选项- 当 base 为整数(例如 2)时,会使 c 程序更快,多次。
- 当 base 是浮点数(例如 2.4)时,它也更快,但非常小。
- 在
-O2
和之间进行比较-O3
,它们在上述测试中非常接近。