我用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
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ang 11
(根据以上答案的提示,我做了更多测试,附加C版本)
在我的linux机器上,时间= 100000000.
测试结果:
Run Code Online (Sandbox Code Playgroud)Java: result: 1.053906e+24, during: 7432 ms C: result: 1.053906e+24, during: 5544 ms Go: result: 1.053906e+24, during: 8.716807708s
pow()或Pow().Run Code Online (Sandbox Code Playgroud)Java: result: 1.543194e+21, during: 630 ms C: result: 1.543194e+21, during: 852 ms Go: result: 1.543194e+21, during: 3.336549272s
x * x改用.Run Code Online (Sandbox Code Playgroud)Java: result: 1.543194e+21, during: 636 ms C: result: 1.543194e+21, during: 340 ms Go: result: 1.543194e+21, during: 115.491272ms
摘要:
go根据最后一次测试,速度真的很快,Java甚至更快C.Java确实有很好的pow()实现.Test.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;
}
}
Run Code Online (Sandbox Code Playgroud)
test.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;
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
编译:
javac Test.java; gcc test.c -lm; go build test.go
Run Code Online (Sandbox Code Playgroud)
跑:
java Test; ./a.out ; ./test
Run Code Online (Sandbox Code Playgroud)
我建议math.Pow(x,y)在Go中实际上x^y没有任何优化整数值,y而Math.pow(x,y)只是x*x为了y==2.至少在两个程序pow中用简单替换时x*x,Java得到6.5秒而Go得到1.4秒.pow相反,我仍然使用Java获得6.5秒,而使用Go获得29.4秒.
不要翻译另一种语言.在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
}
Run Code Online (Sandbox Code Playgroud)
输出:
$ 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
$
Run Code Online (Sandbox Code Playgroud)
你得到了什么结果?