gpt4 book ai didi

java - 为什么我测试 golang goroutine 比 java Thread 慢

转载 作者:IT王子 更新时间:2023-10-29 01:58:49 26 4
gpt4 key购买 nike

======================编辑2016年05月27日16:55解决================= ======

这个问题解决了!感谢@Paul Hankin,你是对的! Java 擅长做“for() {i = i + 1}”,所以当我将代码更改为“for() {i = i + i}”时,java 输了。

(PS:使用Java ExecutorService确实让java结果不错,但还是不如goroutine,这里没有ExecutorService的例子)

Java 代码:

import java.util.ArrayList;
import java.util.List;


public class Test {
public static void main(String args[]) throws InterruptedException {
List<Thread> threads = new ArrayList<Thread>();


for(int i = 0; i < 10; i ++) {
threads.add(new Thread(new RunableAdd()));
}

long timeStart = System.currentTimeMillis();

for(Thread t: threads) {
t.start();
}


for(Thread t: threads) {
t.join();
}


System.out.println("Time Use : " + (System.currentTimeMillis() - timeStart) + "ms");
}


}

class RunableAdd implements Runnable {
@Override
public void run() {
long i = 1;
while(true) {
i += i;
if (i > 1000 * 1000* 1000) {
return;
}
}
}
}

Golang 代码:

package main

import (
"fmt"
"time"
)

func main() {
chanSignal := make(chan bool)

startTime := time.Now()

goroutineNum := 10

for i := 0; i < goroutineNum; i++ {
go func() {
j := 1
for {
j = j + j
if j > 1000*1000*1000 {
chanSignal <- true
return
}
}
}()
}

for i := 0; i < goroutineNum; i++ {
<-chanSignal
}

fmt.Println(time.Since(startTime))
}

结果:

线程/goroutine 数量:10

java : Time Use : 4ms
golang : 19.105µs

线程/goroutine 数量:100

java : Time Use : 27ms
golang : 180.272µs

线程/协程数量:1000

java: Time Use : 512ms
golang : 1.565521ms

原来golang好,java擅长“i = i + 1”,

有趣的是,当goroutine num加10时,耗时不到10倍。

===============================结束=============== =====================

我今天用java线程测试golang goroutine,我认为golang goroutine应该比java Thread快,但我的测试结果表明java线程获胜。

环境:Java 1.8 golang 1.6

cpu是4核

$ cat /proc/cpuinfo | grep 'core id'
core id : 0
core id : 0
core id : 1
core id : 1

Java代码:

import java.util.ArrayList;
import java.util.List;


public class Test {
public static void main(String args[]) throws InterruptedException {
List<Thread> threads = new ArrayList<Thread>();


for(int i = 0; i < 100; i ++) {
threads.add(new Thread(new RunableAdd()));
}

long timeStart = System.currentTimeMillis();

for(Thread t: threads) {
t.start();
}


for(Thread t: threads) {
t.join();
}


System.out.println("Time Use : " + (System.currentTimeMillis() - timeStart) + "ms");
}


}

class RunableAdd implements Runnable {
@Override
public void run() {
int i = 0;
while(true) {
i ++;
if (i == 10 * 1000* 1000) {
return;
}
}
}
}

golang代码:

package main

import (
"fmt"
"time"
)

func main() {
chanSignal := make(chan bool)

startTime := time.Now()

goroutineNum := 100

for i := 0; i < goroutineNum; i++ {
go func() {
j := 0
for {
if j == 10*1000*1000 {
chanSignal <- true
return
} else {
j = j + 1
}
}
}()
}

for i := 0; i < goroutineNum; i++ {
<-chanSignal
}

fmt.Println(time.Since(startTime))
}

结果是:

当我设置线程数 10 时:

Java : Time Use : 18ms
golang : 50.952259ms

线程数 100:

Java : Time Use : 88ms
golang : Time Use : 458.239685ms

线程数 1000:

Java : Time Use : 1452ms
golang : 4.701811465s

Java Thread 真的比 golang goroutine 快吗?还是我的程序出错了?

最佳答案

基准测试很难做到正确,当您在衡量另一件事时,很容易认为您正在衡量一件事(goroutines/线程的成本)。我认为这就是这里发生的事情。

例如,线程/协程中的内部循环在两个程序中是不一样的。重写 goroutine 使其更像 java 代码:

for j := 0; j != 10*1000*1000; j++ {}
chanSignal <- true

导致运行速度提高 2 倍。

当我在我的机器上运行它时,这仍然留下了显着的性能差距——go 代码在 1000 个 goroutine 上需要 663 毫秒,而 java 代码在 1000 个线程上需要 55 毫秒。也许正在发生的事情是 JVM 在线程的 run 方法中执行了几次之后 JIT 掉了无用的循环。

这里有一些证据表明 goroutine 的成本无关紧要。只需连续执行代码,我的机器上的运行时间为 2.55 秒:

package main

import (
"fmt"
"time"
)

func main() {
goroutineNum := 1000
startTime := time.Now()
for i := 0; i < goroutineNum; i++ {
for j := 0; j < 1000*1000*10; j++ {
}
}
fmt.Println(time.Since(startTime))
}

这段代码基于 goroutine 的版本在 4 个处理器上运行了 663 毫秒,这只是串行代码(在我的机器上)所用时间 2.55 秒的四分之一多一点。所以这确实是非常高效的并行性,goroutines 的成本可以忽略不计。

所以我认为您主要是在对 java 和 go 执行空循环的效率进行基准测试。看起来这是 JIT 的完美用例,您会在 Java 代码出色的运行时性能中看到这一点。

关于java - 为什么我测试 golang goroutine 比 java Thread 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37475471/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com