首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类中的代码速度变慢。迭代计数错误?

类中的代码速度变慢。迭代计数错误?
EN

Stack Overflow用户
提问于 2020-06-24 03:15:47
回答 1查看 59关注 0票数 1

由于某些原因,以下代码中的执行时间增加了大约(10:1) (4min vs 40min):

代码语言:javascript
复制
def E_site(lattice, i, j):
    N = len(lattice)
    Nb = lattice[(i+1)%N,j] + lattice[(i-1)%N,j] + lattice[i,(j+1)%N] + lattice[i, (j-1)%N]
    return -lattice[i, j]*Nb

def metropolis(lattice, T, Neq):
    for n in range(Neq):
        N = len(lattice)
        i = np.random.randint(0, N)
        j = np.random.randint(0, N)
        Ei = E_site(lattice, i, j)
        lattice[i, j] *= -1
        Ef = E_site(lattice, i, j)
        dE = Ef - Ei
        if dE < 0 or  np.random.rand() < np.exp(-dE/T):
            pass
        else:
            lattice[i,j] *= -1
    return lattice
def equilibrate(lattice, T, N_equilibration, show_stats):
    if show_stats == False:
        lattice = metropolis(lattice, T, N_equilibration)
        return lattice

def simulate_temperatures(Ti, Tmax, Tstep, N_eq, N_post):
    avg_m_list, avg_E_list = [], []
    T = Ti
    while(T <= Tmax):
        s = time.clock()
        if T <= 2:
            N_eq = int(1e3)
            lattice = init_lattice(20,0.5)
            eq_lattice = equilibrate(lattice, T, N_eq, False)
        else:
            lattice = init_lattice(20,0.5)
            eq_lattice = equilibrate(lattice, T, N_eq, False)
        E, m = [], []
        for i in range(N_post):
            lattice = metropolis(eq_lattice,T,N_eq)
            E.append(total_avg_E(lattice))
            m.append(calcMag(lattice))
        T += Tstep

代码2

代码语言:javascript
复制
    def E_site(self, i, j):
        N = len(self.lattice)
        Nb = self.lattice[(i+1)%N,j] + self.lattice[(i-1)%N,j] + self.lattice[i,(j+1)%N] +     self.lattice[i, (j-1)%N]
        return -self.lattice[i, j]*Nb

    def alternative_metropolis(self, Neq, T):
        for n in range(Neq):
            N = len(self.lattice)
            i = np.random.randint(0, N)
            j = np.random.randint(0, N)
            Ei = self.E_site(i, j)
            self.lattice[i, j] *= -1
            Ef = self.E_site(i, j)
            dE = Ef - Ei
            if dE < 0 or  np.random.rand() < np.exp(-dE/T):
                pass
            else:
                self.lattice[i,j] *= -1


    def alternative_several_temperatures(self, Ti, Tf):
        Tlist = np.arange(Ti, Tf, 0.1)
        for T in Tlist:
            s = time.clock()
            for i in range(len(self.lattice)):
                for j in range(len(self.lattice)):
                    if random() < 0.49: 
                        self.lattice[i,j] = 1
                    else:
                        self.lattice[i,j] = -1
            self.alternative_metropolis(int(1e7), T)

我把在某个时刻调用的所有函数放在一起,让你检查它们看起来是一样的,除了代码2在一个类里面。然后,在Npost的Code1 > simulate_temperatures > for循环中,有一个对metropolis的调用。大都会内部循环,将完成Npost*Neq次。因此,如果Npost = 1e4,Neq = 1e3,那么内部大都市循环总共执行1e7次。

如果您转到代码2中的方法alternative_several_temperatures,您会看到alternative_metropolis方法有一个参数1e7,这是alternative_metropolis内的循环将被执行的次数。因此,所有的函数在我看来都是一样的,为什么代码2在40min运行,而代码1在Npost = 1e4,Neq = 1e3的情况下运行4分钟?我做错了什么数学题吗?

*实际上,由于平衡函数调用,代码2做了更多的迭代。

EN

回答 1

Stack Overflow用户

发布于 2020-06-24 03:29:06

这里发生了很多事情,所以很难确定,但我假设您每秒调用此代码数千次。如果是这样的话,这很可能是罪魁祸首:

代码语言:javascript
复制
    i = np.random.randint(0, N)
    j = np.random.randint(0, N)

这种现象被称为“熵池耗尽”。本质上,您的计算机通过从各种来源(键盘敲击、鼠标移动、环境温度等)累积熵来生成熵。这种熵积累的速度相当慢。当您请求额外的随机整数并且熵池已经耗尽时,机器会阻塞,等待更多的熵变得可用。

要解决这个问题,您需要使用一个较小的“真”随机数子集和一个伪随机数生成器来填补空白。例如,您可以创建一个“熵提供者”类,它每10,000次调用才用一个新的随机整数重新设定PRNG的种子。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62542184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档