让golang和C++做两个长度相同的数组对位元素的相乘然后再相加求和(类似于矩阵相乘),golang版本go 1.13,VScode编译,C++采用VS2015编译,release版本执行
C++代码
void multiply_Array()
{
int x, y;
double result = 0;
LARGE_INTEGER t1;
LARGE_INTEGER t2;
LARGE_INTEGER freq = { 0 };
double timeCost = 0;
QueryPerformanceFrequency(&freq);
srand((unsigned)time(NULL));
x = 2;
y = 100000;
QueryPerformanceCounter(&t1);
//semiResult保存对位数组元素相乘的结果
double* semiResult = (double*)malloc(y * sizeof(double));
//声明二维数组,数组的行数x就是2(用这两行的对应元素相乘),列数y可变,改变计算量比较C++与go在不同计算量时的效率
//下面的代码为二维数组分配内存,这种方法可以为整个二维数组申请连续的空间
double **matrix = (double **)malloc(x * sizeof(double *));
matrix[0] = (double *)malloc(x * y * sizeof(double));
for (int i = 1; i < x; i++)
matrix[i] = matrix[0] + i * y;
//空间申请完毕
//将数组的元素利用随机数初始化为0-1之间的double类型值
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
matrix[i][j] = (double)rand() / RAND_MAX;
}
//不同行、相同列的元素相乘结果放入semiResult数组
for (int j = 0; j < y; j++)
{
semiResult[j] = matrix[0][j] * matrix[1][j];
}
//semiResult数组元素求和
for (int j = 0; j < y; j++)
{
result = result + semiResult[j];
}
printf("%.4lf\n", result);
QueryPerformanceCounter(&t2);
timeCost = (double)(t2.QuadPart - t1.QuadPart) / (double)freq.QuadPart;
printf("time cost = %lf", timeCost);
//释放内存
free(semiResult);
free(matrix[0]);
free(matrix);
}
主函数
int main()
{
multiply_Array();
getchar();
return 0;
}
golang代码
package main
import "fmt"
import "math/rand"
import "time"
//goroutine只能用于函数,为了查看启用协程与不启用协程的效率,将随机数初始化数组元素的内容写到函数里
func randNumberGen(a *float64) {
*a = float64(rand.Intn(10000))/10000.0
}
//为了启用协程将数组元素相乘写入独立函数
func multiply(a *float64,b *float64,c *float64) {
*c = (*a) * (*b)
}
func main(){
var x int=2
var y int =100000
var result float64 = 0
var timeCost float64 = 0
//开始计时
var begin int64 = time.Now().UnixNano()
var semiResult []float64 = make([]float64,y)
var matrix [][]float64 = make([][]float64,x)
for i:=0;i<x;i++{
matrix[i] = make([]float64,y)
}
rand.Seed(time.Now().UnixNano())
//二维数组赋初值
for i:=0;i<x;i++{
for j:=0;j<y;j++{
//不使用goroutine时用这句
matrix[i][j] = float64(rand.Intn(10000))/10000.0
//使用goroutine时用下面这句
//go randNumberGen(&matrix[i][j])
}
}
//每列求和
for j:=0;j<y;j++{
//不使用goroutine时用这句
semiResult[j] = matrix[0][j]*matrix[1][j]
//使用goroutine时用下面这句
//go multiply(&matrix[0][j],&matrix[1][j],&semiResult[j])
}
//最终求和
for j:=0;j<y;j++{
result = result + semiResult[j]
}
var end int64 = time.Now().UnixNano()
timeCost = float64((end - begin))/1e9
fmt.Println(result)
fmt.Printf("time cost = %f",timeCost)
}
改变y的值可以调整计算量以比较golang与C++计算效率
y=10 :C++耗时0.000122s;go不使用goroutine耗时0.000000;go使用goroutine耗时0.000000
y=100:C++耗时0.000150s;go不使用goroutine耗时0.000000;go使用goroutine耗时0.000972
y=1000:C++耗时0.000194s;go不使用goroutine耗时0.000000;go使用goroutine耗时0.003004
y=10000:C++耗时0.001219s;go不使用goroutine耗时0.000988;go使用goroutine耗时0.009974
y=100000:C++耗时0.009037s;go不使用goroutine耗时0.006013;go使用goroutine耗时0.081749
y=1000000:C++耗时0.083905s;go不使用goroutine耗时0.076828;go使用goroutine耗时0.749993
可以看出来不使用goroutine时golang的效率比C++高,使用goroutine时效率反倒不如C++,这主要是因为goroutine需要配置线程耗费了资源,在每一个线程工作量很低的情况下,启用多线程反倒拖累了效率,不过可以看出golang的效率十分的高,不用goroutine时效率甚至超过了C++.