有什么可能的方法可以使这段代码更高效、更快吗?

发布于 2025-01-10 03:51:18 字数 2879 浏览 0 评论 0原文

import numpy as np
import matplotlib.pyplot as plt
import time
from numba import njit, prange

@njit('int_(int_, int_, int_[::1])')
def aloha(N, M, tmp):
    tmp.fill(0)
    for i in range(M):
        rnd = np.random.randint(0, N)
        tmp[rnd] += 1
    success = 0
    for i in range(N):
        success += tmp[i] == 1
    return success

@njit('float64(int_, int_, int_[::1])')
def repetition(I,M,tmp):
    s = 0
    for i in range(I):
        s += aloha(12, M, tmp)
    return s/I
    
@njit('float64[::1](int_)')
def simulation(M):
    tmp = np.zeros(12, np.int_) # Preallocated buffer
    success_0 = 0
    success_1 = 0
    success_2 = 0
    M0 = M
    M1 = M
    M2 = M
    s = 0
    # 1-5
    for j in range(5):
        s = 0
        # CE Lv 0
        s = repetition(8,round(M0),tmp)
        M0 -= s
        success_0 += s
        # CE Lv 1
        s = repetition(32,round(M1),tmp)
        M1 -= s
        success_1 += s
        # CE Lv 2
        s = repetition(128,round(M2),tmp)
        M2 -= s
        success_2 += s
    # 6-10
    for j in range(5):
        s = 0
        # CE Lv 0
        s = repetition(32,round(M0),tmp)
        M0 -= s
        success_0 += s
         # CE Lv 1 and 2
        M1 = M1 + M2
        s = repetition(128,round(M1),tmp)
        M1 -= s
        success_1 += s
        success_2 += s
    # 11-15
    for j in range(5):
        s = 0
        # CE Lv 0
        M0 = M0 + M1
        s = repetition(128,int(M0),tmp)
        M0 -= s
        success_0 += s
        success_1 += s
        success_2 += s
    return np.array([success_0/M,success_1/M,success_2/M], dtype=np.float64)

@njit('float64[::1](int_, int_)', parallel=True)
def compute_ps_avg(m, sample_size):
    s0 = np.zeros(sample_size, dtype=np.float64)
    s1 = np.zeros(sample_size, dtype=np.float64)
    s2 = np.zeros(sample_size, dtype=np.float64)
    for i in prange(sample_size):
        arr = simulation(m)
        s0[i]= arr[0]
        s1[i] = arr[2]
        s2[i] = arr[1]
    s0_result = np.mean(s0)
    s1_result = np.mean(s1)
    s2_result = np.mean(s2)
    return np.array([s0_result,s1_result,s2_result])

if __name__ == "__main__":
    start = time.perf_counter() 
    SAMPLE_SIZE = 100
    M = np.linspace(10,100,10)
    Result = [compute_ps_avg(m, SAMPLE_SIZE) for m in M]
    print(Result)
    Flatted = np.reshape(Result,-1)
    s0 = Flatted[0::3]
    s1 = Flatted[1::3]
    s2 = Flatted[2::3]
    elapsed = (time.perf_counter() - start)
    print("Time used:",elapsed)
    plt.scatter(M,s0,marker='s', facecolors='none', edgecolors='b')
    plt.scatter(M,s1,marker='o')
    plt.scatter(M,s2,s=80, facecolors='none', edgecolors='r')
    plt.ylim(ymin=0)
    plt.ylim(ymax=1.1)
    plt.xticks(M)
    plt.show()

最终目标是使用 SAMPLE_SIZE = 10^7 运行该程序,并运行大约 1000 秒。我已经在互联网上搜索并使用 numba 来加快一点速度,但这还不够。有什么办法可以让它更高效、更快呢?感谢您给我建议。这会对我有很大帮助,非常感谢。

import numpy as np
import matplotlib.pyplot as plt
import time
from numba import njit, prange

@njit('int_(int_, int_, int_[::1])')
def aloha(N, M, tmp):
    tmp.fill(0)
    for i in range(M):
        rnd = np.random.randint(0, N)
        tmp[rnd] += 1
    success = 0
    for i in range(N):
        success += tmp[i] == 1
    return success

@njit('float64(int_, int_, int_[::1])')
def repetition(I,M,tmp):
    s = 0
    for i in range(I):
        s += aloha(12, M, tmp)
    return s/I
    
@njit('float64[::1](int_)')
def simulation(M):
    tmp = np.zeros(12, np.int_) # Preallocated buffer
    success_0 = 0
    success_1 = 0
    success_2 = 0
    M0 = M
    M1 = M
    M2 = M
    s = 0
    # 1-5
    for j in range(5):
        s = 0
        # CE Lv 0
        s = repetition(8,round(M0),tmp)
        M0 -= s
        success_0 += s
        # CE Lv 1
        s = repetition(32,round(M1),tmp)
        M1 -= s
        success_1 += s
        # CE Lv 2
        s = repetition(128,round(M2),tmp)
        M2 -= s
        success_2 += s
    # 6-10
    for j in range(5):
        s = 0
        # CE Lv 0
        s = repetition(32,round(M0),tmp)
        M0 -= s
        success_0 += s
         # CE Lv 1 and 2
        M1 = M1 + M2
        s = repetition(128,round(M1),tmp)
        M1 -= s
        success_1 += s
        success_2 += s
    # 11-15
    for j in range(5):
        s = 0
        # CE Lv 0
        M0 = M0 + M1
        s = repetition(128,int(M0),tmp)
        M0 -= s
        success_0 += s
        success_1 += s
        success_2 += s
    return np.array([success_0/M,success_1/M,success_2/M], dtype=np.float64)

@njit('float64[::1](int_, int_)', parallel=True)
def compute_ps_avg(m, sample_size):
    s0 = np.zeros(sample_size, dtype=np.float64)
    s1 = np.zeros(sample_size, dtype=np.float64)
    s2 = np.zeros(sample_size, dtype=np.float64)
    for i in prange(sample_size):
        arr = simulation(m)
        s0[i]= arr[0]
        s1[i] = arr[2]
        s2[i] = arr[1]
    s0_result = np.mean(s0)
    s1_result = np.mean(s1)
    s2_result = np.mean(s2)
    return np.array([s0_result,s1_result,s2_result])

if __name__ == "__main__":
    start = time.perf_counter() 
    SAMPLE_SIZE = 100
    M = np.linspace(10,100,10)
    Result = [compute_ps_avg(m, SAMPLE_SIZE) for m in M]
    print(Result)
    Flatted = np.reshape(Result,-1)
    s0 = Flatted[0::3]
    s1 = Flatted[1::3]
    s2 = Flatted[2::3]
    elapsed = (time.perf_counter() - start)
    print("Time used:",elapsed)
    plt.scatter(M,s0,marker='s', facecolors='none', edgecolors='b')
    plt.scatter(M,s1,marker='o')
    plt.scatter(M,s2,s=80, facecolors='none', edgecolors='r')
    plt.ylim(ymin=0)
    plt.ylim(ymax=1.1)
    plt.xticks(M)
    plt.show()

The Ultimate goal is to run this program with SAMPLE_SIZE = 10^7 and run it with around 1000s. I already search on the internet and use numba to speed up a little bit but it doesn't enough. Is there any way to make it more efficient and faster? Thanks for giving me suggestions. It will help me a lot thank you so much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文