Go语言以高并发闻名于世,牛皮不能光靠吹,今天我们就来做一个对比试验,体会一下Go在并发方面的巨大优势!靶子就瞄准Java,谁让它是后端开发语言的老大哥呢。
基本任务:初始化一个100*100的矩阵,矩阵每个元素是从[0,1)随机取的双精度浮点数,计算矩阵跟自身相乘,需要100万次乘法运算。
机器配置:Linux云主机,8核16G内存。
分别尝试开10、100、1000、10000、100000、1000000个线程(协程)执行上述的基本任务。
试验结果:
测试运行时间/ms | ||||||
并发度 | 10 | 100 | 1000 | 10000 | 100000 | 1000000 |
go | 0 | 5 | 56 | 507 | 5062 | 50457 |
java | 36 | 109 | 611 | 3063 | 27684 | 285971 |
速度差异很明显,go以绝对优势领先。而且随着并发度的增加,go的耗时呈线性增长;java则愈显吃力,Hold不住这么高的并发量。go可以轻松地把8个核用满,而java最多只用到5.2个核。
最后附上测试代码,如有问题,还请指正。
go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package main import ( "fmt" "math/rand" "os" "strconv" "sync" "time" ) func MatrixMultiply(A, B [100][100]float64) { rect := [100][100]float64{} for i := 0; i < 100; i++ { for j := 0; j < 100; j++ { prod := 0.0 for k := 0; k < 100; k++ { prod += A[i][k] * B[k][j] } rect[i][j] = prod } } // fmt.Println("goroutine finish") } func main() { A := [100][100]float64{} for i := 0; i < 100; i++ { for j := 0; j < 100; j++ { A[i][j] = rand.Float64() //[0,1)上的随机数 } } p, _ := strconv.Atoi(os.Args[1]) //p个并发协程 fmt.Printf( "concurrency %d\n" , p) begin := time.Now() wg := sync.WaitGroup{} wg.Add(p) for i := 0; i < p; i++ { go func () { defer wg.Done() MatrixMultiply(A, A) }() } wg.Wait() fmt.Printf( "use time %d ms\n" , time.Since(begin).Milliseconds()) } |
java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import java.util.Random; public class MatMul extends Thread{ private double [][] A; private double [][] B; MatMul( double [][] X, double [][] Y){ A=X; B=Y; } @Override public void run(){ double [][] rect= new double [ 100 ][ 100 ]; for ( int i= 0 ;i< 100 ;i++){ for ( int j= 0 ;j< 100 ;j++){ double prod= 0 ; for ( int k= 0 ;k< 100 ;k++){ prod+=A[i][k]*B[k][j]; } rect[i][j]=prod; } } // System.out.println("thread finish"); } public static void main(String[] args) { Random r = new Random( 1 ); double [][] A= new double [ 100 ][ 100 ]; for ( int i= 0 ;i< 100 ;i++){ for ( int j= 0 ;j< 100 ;j++){ A[i][j]=r.nextDouble(); //[0,1)上的随机数 } } int p=Integer.parseInt(args[ 0 ]); //p个并发线程 System.out.println( "concurrency " +p); MatMul[] threads= new MatMul[p]; long startTime = System.currentTimeMillis(); for ( int i= 0 ;i<p;i++){ MatMul thread= new MatMul(A,A); threads[i]=thread; thread.start(); } for ( int i= 0 ;i<p;i++){ try { threads[i].join(); } catch (InterruptedException e) { System.out.println( "Thread interrupted." ); } } long endTime = System.currentTimeMillis(); System.out.println( "use time " +(endTime-startTime)+ " ms" ); } } |
本文来自博客园,作者:高性能golang,转载请注明原文链接:https://www.cnblogs.com/zhangchaoyang/p/15126137.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决