net8 golang python性能比较

net8正式版出来两个月,现在性能到底如何呢,做个简单的例子和其他语言比较一下,测试内容是查找1000000以内的质数,代码不多,但包含了循环计算和Math库函数调用,直观的看一下语言之间差距是多少,心里有个底,测试机是笔记本surface book 2 intel i7 有个四五年了,不过还能跑

单线程篇

首先来看看google的王牌语言golang,语法简单但性能号称不输C++,先看一下go 1.20.2

package main

import (
	"fmt"
	"math"
	"time"
)

func isPrime(num int) bool {
	if num <= 1 {
		return false
	}
	for i := 2; i <= int(math.Sqrt(float64(num))); i++ {
		if num%i == 0 {
			return false
		}
	}
	return true
}

func countPrimes(n int) int {
	count := 0
	for i := 2; i < n; i++ {
		if isPrime(i) {
			count++
		}
	}
	return count
}

func main() {
	num := 1000000

	startTime := time.Now()
	result := countPrimes(num)
	endTime := time.Now()

	fmt.Printf("The number of prime numbers less than %d is: %d\n", num, result)
	fmt.Printf("Execution time: %v\n", endTime.Sub(startTime))
}

编译之后看看耗时是多少

然后看看net6

using System;
using System.Diagnostics;

namespace FindPrimeNet6
{
    class Program
    {
        static bool IsPrime(int num)
        {
            if (num <= 1)
            {
                return false;
            }
            for (int i = 2; i <= Math.Sqrt(num); i++)
            {
                if (num % i == 0)
                {
                    return false;
                }
            }
            return true;
        }

        static int CountPrimes(int n)
        {
            int count = 0;
            for (int i = 2; i < n; i++)
            {
                if (IsPrime(i))
                {
                    count++;
                }
            }
            return count;
        }

        static void Main(string[] args)
        {
            int num = 1000000;

            Stopwatch timer = Stopwatch.StartNew();

            int result = CountPrimes(num);

            timer.Stop();

            Console.WriteLine($"The number of prime numbers less than {num} is: {result}");
            Console.WriteLine($"Execution time: {timer.ElapsedMilliseconds:F4} ms");
        }
    }
}

运行一下看看

然后重头来了net8 开启aot怎么样呢

看来速度没提升,应该是启动速度提高了

然后我们再看看大家心目中最慢的python,装了3.11.7版本

#import numba
import math
import time

#@numba.jit
def is_prime(num):
    if num <= 1:
        return False
    for i in range(2, int(math.sqrt(num)) + 1):
        if num % i == 0:
            return False
    return True
    
#@numba.jit
def count_primes(n):
    count = 0
    for i in range(2, n):
        if is_prime(i):
            count += 1
    return count

num = 1000000
start_time = time.perf_counter()
result = count_primes(num)
end_time = time.perf_counter()

time_elapsed = end_time - start_time

print(f"The number of prime numbers less than {num} is: {result}")
print(f"Execution time: {time_elapsed*1000:.4f}ms")

看看普通模式跑跑要多少毫秒

竟然3秒7 是golang10倍,然后让我们开了jit再跑一次

看起来 并没有差前两个语言很多

然后打包exe再执行一次 差强人意哈哈 单线程性能就这样了,参考一下 。

并行计算篇

测试完上面的,各个语言粉丝说不服,根本没有发挥出优势,结果并不能说明真正的快慢,那我又重新写了一下这三个语言的并行计算方法,比较这种情况到底谁快,结果可能你想不到。

首先还是golang 这次采用routine协程方式计算代码贴上

package main

import (
	"fmt"
	"sync"
	"time"
)

func isPrime(num int) bool {
	if num <= 1 {
		return false
	}

	for i := 2; i*i <= num; i++ {
		if num%i == 0 {
			return false
		}
	}

	return true
}

func countPrimes(start, end int, resultChan chan int, wg *sync.WaitGroup) {
	defer wg.Done()

	count := 0
	for i := start; i < end; i++ {
		if isPrime(i) {
			count++
		}
	}

	resultChan <- count
}

func main() {

	startTime := time.Now()
	
	num := 1000000
	goroutines := 10
	results := make(chan int, goroutines)

	var wg sync.WaitGroup
	wg.Add(goroutines)

	step := num / goroutines

	for i := 0; i < goroutines; i++ {
		start := i * step
		end := (i + 1) * step
		if i == goroutines-1 {
			end = num
		}
		go countPrimes(start, end, results, &wg)
	}

	wg.Wait()
	close(results)

	total := 0
	for result := range results {
		total += result
	}
	endTime := time.Now()
	fmt.Printf("Total number of primes: %d\n", total)
	fmt.Printf("Execution time: %v\n", endTime.Sub(startTime))
}

编译运行一下试试

golang 一下就赶上来了,成绩不错恭喜恭喜,速度还可以就是写法会麻烦了一些

看看net8 代码先上来,记得要编译release版本

using System;
using System.Diagnostics;

namespace FindPrime
{
    class Program
    {
        static int CountPrimes()
        {
            const int maxNumber = 1000000;
            int primeCount = 0;

            bool[] isPrime = new bool[maxNumber + 1];
            for (int i = 2; i <= maxNumber; i++)
            {
                isPrime[i] = true;
            }

            Parallel.For(2 , maxNumber + 1, i =>
            {
				for (int j = 2; j <= Math.Sqrt(i); j++)
				{
					if (i % j == 0)
					{
						isPrime[i] = false;
						break;
					}
				}
                
            });

            for (int i = 2; i <= maxNumber; i++)
            {
                if (isPrime[i])
                {
                    primeCount++;
                }
            }

            return primeCount;
        }

        static void Main(string[] args)
        {
            Stopwatch timer = Stopwatch.StartNew();

            int result = CountPrimes();

            timer.Stop();

            Console.WriteLine($"The number of prime numbers is: {result}");
            Console.WriteLine($"Execution time: {timer.ElapsedMilliseconds:F4} ms");
        }
    }
}

跑起来看看,貌似负优化,其实之前在amd ryzen cpu上并行是比单线程快的,这个优化的不稳定

最后上boss,我们的python大佬要登场了,看看科学界的宠儿到底怎么样

import numpy as np
import time

start_time = time.perf_counter()

# 创建包含所有整数的数组
numbers = np.arange(2, 1000000)

# 创建布尔数组,初始化为 True
is_prime = np.ones(len(numbers), dtype=bool)

# 筛选法标记非质数
for i in range(2, int(np.sqrt(1000000)) + 1):
    if is_prime[i - 2]:
        is_prime[i * 2 - 2::i] = False

# 获取所有质数
primes = numbers[is_prime]

# 打印质数
end_time = time.perf_counter()
time_elapsed = end_time - start_time

print(f"The number of prime numbers is: {len(primes)}")
print(f"Execution time: {time_elapsed*1000:.4f}ms")

不编译exe了直接脚本跑,结果出来了,快golang10倍,所以说数值计算还是来python吧,没啥说的 散会

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

充值内卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值