cython vs numba的性能

时间:2018-10-13 12:53:44

标签: python cython numba

嘿,我目前正在使用Python的模块进行热力学液相平衡。为此,我需要编写活动系数模型(如NRTL),其中涉及多个求和。为了增强模块的性能,我尝试使用numba来实现该功能:

AppDomain

我正在尝试新的选择,例如cython,但是我的表现不如numbas的jit好。

@jit(cache=True)
def NRTL(X,T,g, alpha, g1):
'''
NRTL activity coefficient model.

input
X: array like, vector of molar fractions
T: float, absolute temperature in K.
g: array like, matrix of energy interactions in K.
g1: array_like, matrix of energy interactions in K^2
alpha: float, aleatory factor.

tau = ((g + g1/T)/T)

output
lngama: array_like, natural logarithm of activify coefficient
'''

tau = g + g1*T
tau /= T

nc=len(X)
G=np.exp(-alpha*tau)
lngama=np.zeros_like(X)
for i in range(nc):
    SumC=SumD=SumE=0
    for j in range(nc):
        A=X[j]*G[i,j]
        SumA=SumB=0
        for k in range(nc):
            SumA +=X[k]*G[k,j]
            SumB +=X[k]*G[k,j]*tau[k,j]
        SumC +=A/SumA*(tau[i,j]-SumB/SumA)
        SumD+=X[j]*G[j,i]*tau[j,i]
        SumE+=X[j]*G[j,i]
    lngama[i]=SumD/SumE+SumC
return lngama

我使用以下参数评估该功能:

import numpy as np
cimport numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cdef double[:] nrtlaux(double [:] X, double [:,::1] G, double [:,::1] tau, int nc):
cdef int i, j, k
cdef double A, SumA, SumB, SumC, SumD, SumE, aux1, aux2

cdef double [:] lngama = np.zeros(nc)

for i in range(nc):
    SumC = SumD = SumE = 0.
    for j in range(nc):
        A = X[j]*G[i,j]
        SumA = SumB = 0.
        for k in range(nc):
            aux1 = X[k]*G[k,j]
            SumA += aux1
            SumB += aux1*tau[k,j]
        SumC += A/SumA*(tau[i,j]-SumB/SumA)
        aux2 = X[j]*G[j,i]
        SumD += aux2*tau[j,i]
        SumE += aux2
    lngama[i] = SumD/SumE+SumC
return lngama

def NRTL(np.ndarray[double, ndim=1] X, double T, np.ndarray[double, ndim=2] g,
       np.ndarray[double, ndim=2] alpha, np.ndarray[double, ndim=2] g1):
cdef int nc = len(X)
cdef:
    double[:,::1] tau = (g/T + g1)
    double[:,::1] G  = np.exp( -alpha * tau )

lngama = nrtlaux(X, G, tau, nc)

return np.asarray(lngama)

我得到了以下结果:

X = np.array([0.5,0.4,0.1])
g = np.array([[0,35.00002657,463.719316],[341.00001923,0,96.02154497],[1194.42262, 534.77089478,0]])
alpha = np.array([[0,0.3456916919878884,0.242020522],[0.3456916919878884,0,0.54 ],[0.242020522,0.54 ,0]])
g1 = np.zeros_like(g)
T = 350. 

我对jitted函数的良好结果感到惊讶,我还是cython的初学者,所以我希望对提高性能有什么建议?

0 个答案:

没有答案