ãŸããã
ç§ãä»äºããã幞éãª
åéã¯ãå¿èã®èšç®é»æ°ççåŠãšåŒã°ã
ãŠããŸã ã å¿è掻åã®ççåŠã¯ãåã
ã®å¿ç现èã®ã¬ãã«ã§çºçãã黿°çããã»ã¹ã«ãã£ãŠæ±ºå®ãããŸãã ãããã®é»æ°ããã»ã¹ã¯ã枬å®ã容æãªé»çãäœãåºããŸãã ããã«ãé黿°ã®æ°åŠçã¢ãã«ã®æ çµã¿ã§éåžžã«ãã説æãããŠããŸãã ããã§ãå¿èã®åããå³å¯ã«æ°åŠçã«èšè¿°ãããŠããŒã¯ãªæ©äŒãçããŸããããã¯ãå€ãã®å¿èç
ã®æ²»çæ¹æ³ãæ¹åããããšãæå³ããŸãã
ãã®åéã§ã®ä»äºäžã«ãããŸããŸãªã³ã³ãã¥ãŒãã£ã³ã°ãã¯ãããžãŒã䜿çšããçµéšãç©ãã§ããŸããã ãã®åºçç©ã®äžéšãšããŠã ãã§ãªããç§ã«ãšã£ãŠè峿·±ããããããªãããã€ãã®è³ªåã«çããããšããŸãã
Scientific Pythonã«ã€ããŠç°¡åã«
倧åŠã®æåã®ã³ãŒã¹ããå§ããŠãæ°å€ã¢ã«ãŽãªãºã ã®è¿
éãªéçºã®ããã®çæ³çãªããŒã«ãèŠã€ããããšããŸããã ããã€ãã®ççŽã«èšã£ãŠéççãªæè¡ãæšãŠãå ŽåãC ++ãšMATLABã®éãèµ°ããŸããã ããã¯ãScientific Python [1]ãçºèŠãããŸã§ç¶ããŸããã
Scientific Pythonã¯ãç§åŠèšç®ãšç§åŠèŠèŠåã®ããã®Pythonã©ã€ãã©ãªã®ã³ã¬ã¯ã·ã§ã³ã§ãã ç§ã®ä»äºã§ã¯ãç§ã®ããŒãºã®çŽ90ïŒ
ãã«ããŒãã以äžã®ããã±ãŒãžã䜿çšããŸãã
åœ¹è· | 説æ |
---|
ãã³ã㌠| åºæ¬çãªã©ã€ãã©ãªã®1ã€ã䜿çšãããšãMATLABã¹ã¿ã€ã«ã®åäžãªããžã§ã¯ããšããŠå€æ¬¡å
é
åãæäœã§ããŸãã ç·åœ¢ä»£æ°ãããŒãªãšå€æãä¹±æ°ã®åŠçãªã©ã®åºæ¬æé ã®å®è£
ãå«ãŸããŸãã |
ã·ã㌠| NumPyæ¡åŒµã«ã¯ãæé©åã¡ãœããã®å®è£
ãæŸé»ããããããªãã¯ã¹ã®åŠçãçµ±èšãªã©ãå«ãŸããŸãã |
ãã³ã | 倿¬¡å
ããŒã¿ãšçµ±èšã®åæçšã®åå¥ã®ããã±ãŒãžã |
ã·ã³ã㌠| ã·ã³ããªãã¯æ°åŠã®ããã±ãŒãžã |
ããããããªã | äºæ¬¡å
ã°ã©ãã£ãã¯ã¹ã |
ãã€ã2 | VTKã«åºã¥ã3次å
ã°ã©ãã£ãã¯ã¹ã |
ã¹ãã€ã㌠| æ°åŠã¢ã«ãŽãªãºã ã®ã€ã³ã¿ã©ã¯ãã£ããªéçºã«äŸ¿å©ãªIDEã |
Scientific Pythonã§ã¯ãæ°å€ã¢ã«ãŽãªãºã ã®è¿
éãªéçºã®ããã®äŸ¿å©ãªé«ã¬ãã«ã®æœè±¡åãšãææ°ã®éçºèšèªãšã®éã«å€§ããªãã©ã³ã¹ãããããšãããããŸããã ãããããåãã®ãšãããå®ç§ãªããŒã«ã¯ãããŸããã ãããŠãPythonã®ããªãéèŠãªåé¡ã®1ã€ã¯ã䞊åèšç®ã®åé¡ã§ãã
Pythonã§ã®äžŠåèšç®ã®åé¡ã
ãã®èšäºã®äžŠåã³ã³ãã¥ãŒãã£ã³ã°ã«ãã£ãŠãSMP-å
±æã¡ã¢ãªã䜿çšãã察称åãã«ãããã»ãã·ã³ã°ã«ã€ããŠçè§£ã§ããŸãã CUDAãšå
±æã¡ã¢ãªãåããã·ã¹ãã ã®äœ¿çšã¯æ±ããŸããïŒMPIæšæºãæããã䜿çšãããŸãïŒã
åé¡ã¯GILã§ãã GILïŒGlobal Interpreter LockïŒã¯ãè€æ°ã®ã¹ã¬ãããåããã€ãã³ãŒããå®è¡ããã®ãé²ããã¥ãŒããã¯ã¹ã§ãã æ®å¿µãªãããCPythonã®ã¡ã¢ãªç®¡çã·ã¹ãã ã¯ã¹ã¬ããã»ãŒãã§ã¯ãªãããããã®ããã¯ãå¿
èŠã§ãã ã¯ããGILã¯Pythonã®åé¡ã§ã¯ãªããCPythonã€ã³ã¿ãŒããªã¿ãŒã®å®è£
ã®åé¡ã§ãã ããããæ®å¿µãªãããPythonã®æ®ãã®å®è£
ã¯ãé«éãªæ°å€ã¢ã«ãŽãªãºã ã®äœæã«ã¯ããŸãé©ããŠããŸããã
幞ããªããšã«ãçŸåšGILã®åé¡ã解決ããæ¹æ³ã¯ããã€ããããŸãã ããããèæ
®ããŠãã ããã
ãã¹ãã¿ã¹ã¯
Nãã¯ãã«ã®2ã€ã®ã»ãããäžããããŸãïŒ3次å
ãŠãŒã¯ãªãã空éã®
P = {p 1 ãp 2 ã...ãp N }ããã³
Q = {q 1 ãq 2 ã...ãq N } ã æ¬¡å
N x Nã®è¡å
Rãäœæããå¿
èŠããããŸããåèŠçŽ
r iãjã¯æ¬¡ã®åŒã§èšç®ãããŸãã
倧ãŸãã«èšãã°ããã¹ãŠã®ãã¯ãã«éã®ãã¢ã¯ã€ãºè·é¢ã䜿çšããŠè¡åãèšç®ããå¿
èŠããããŸãã ãã®è¡åã¯ãå®éã®èšç®ã§ãã䜿çšãããŸããããšãã°ãRBFè£éãç©åæ¹çšåŒã®æ¹æ³ã«ããç·æ¥ç¶æ
ã§ã®å·®åã®è§£æ±ºãªã©ã§ãã
ãã¹ãå®éšã§ã¯ããã¯ãã«ã®æ°ã¯
N = 5000ã§ããèšç®ã«ã¯ã4ã³ã¢ã®ããã»ããµã䜿çšãããŸããã çµæã¯ã10ã®éå§ã®å¹³åæéã«ãã£ãŠååŸãããŸãã
ãã¹ãã¿ã¹ã¯ã®å®å
šãªå®è£
ã¯ãGitHubã§èŠãããšãã§ããŸã[2]ã
ã@chersayaãããã®ã³ã¡ã³ãã®æ£ããçºèšã ããã§ã¯ããã®ãã¹ãã±ãŒã¹ãäŸãšããŠäœ¿çšããŸãã ãã¢ã¯ã€ãºè·é¢ãæ¬åœã«èšç®ããå¿
èŠãããå Žåã¯ãscipy.spatial.distance.cdist颿°ã䜿çšããããšããå§ãããŸãã
C ++䞊åå®è£
Pythonã§ã®äžŠåèšç®ã®å¹çãæ¯èŒããããã«ããã®ã¿ã¹ã¯ãC ++ã§å®è£
ããŸããã äž»ãªæ©èœã³ãŒãã¯æ¬¡ã®ãšããã§ãã
ãŠãããã»ããµã®å®è£
ïŒ
ãã«ãããã»ããµã®å®è£
ïŒ
ããã§é¢çœãã®ã¯äœã§ããïŒ ãŸããæåã«ãå¥ã®Vector3Dã¯ã©ã¹ã䜿çšããŠã3次å
空éã§ãã¯ãã«ã衚ããŸããã ãã®ã¯ã©ã¹ã®ãªãŒããŒããŒãæŒç®åã*ãã«ã¯ãã¹ã«ã©ãŒç©ã®æå³ããããŸãã ãã¯ãã«ã®ã»ããã衚ãããã«ãstd :: vectorã䜿çšããŸããã 䞊åã³ã³ãã¥ãŒãã£ã³ã°ã§ã¯ãOpenMPãã¯ãããžãŒã䜿çšãããŸããã ã¢ã«ãŽãªãºã ã䞊ååããã«ã¯ããïŒpragma omp parallel forããã£ã¬ã¯ãã£ãã䜿çšããŸãã
çµæïŒ
ãŠãããã»ããµC ++ | 224ããªç§ |
ãã«ãããã»ããµC ++ | 65ããªç§ |
3.45åã®äžŠåå éã¯ãã¯ã¢ããã³ã¢ããã»ããµã«éåžžã«é©ããŠãããšæããŸãã
Pythonã§ã®äžŠåå®è£
1.çŽç²ãªPythonã§ã®åçŽãªå®è£
ãã®ãã¹ãã§ã¯ãç¹å¥ãªããã±ãŒãžã䜿çšããã«ãçŽç²ãªPythonã§ã¿ã¹ã¯ãã©ãã ã解決ããããã確èªãããã£ãã®ã§ãã
ãœãªã¥ãŒã·ã§ã³ã³ãŒãïŒ
def sppyGetR(p, q): R = np.empty((p.shape[0], q.shape[1])) nP = p.shape[0] nQ = q.shape[1] for i in xrange(nP): for j in xrange(nQ): rx = p[i, 0] - q[0, j] ry = p[i, 1] - q[1, j] rz = p[i, 2] - q[2, j] R[i, j] = 1 / (1 + sqrt(rx * rx + ry * ry + rz * rz)) return R
ããã§ã
p ã
qã¯ã次å
ïŒNã3ïŒããã³
ïŒ3ãNïŒã®é
åã®NumPy圢åŒã®å
¥åããŒã¿ã§ãã ãããŠãè¡åRã®èŠçŽ ãèšç®ããæ£çŽãªPythonã«ãŒããç»å ŽããŸãã
çµæïŒ
ãŠãããã»ããµPython | 57 386ããªç§ |
ã¯ããã¯ããæ£ç¢ºã«57000ããªç§ã§ãã ã·ã³ã°ã«ããã»ããµã®C ++ããã256åé
ãå Žæã äžè¬çã«ãããã¯æ°å€èšç®ã®ãªãã·ã§ã³ã§ã¯ãããŸããã
2ãŠãããã»ããµNumPy
äžè¬ã«ãNumPyã䜿çšããŠPythonã§ã³ã³ãã¥ãŒãã£ã³ã°ããå Žåã䞊ååŠçã«ã€ããŠãŸã£ããèããå¿
èŠããªãå ŽåããããŸãã ãããã£ãŠãããšãã°ã2ã€ã®è¡åã«NumPyãä¹ç®ããæé ã¯ãC ++ïŒMKLãŸãã¯ATLASïŒã®äœã¬ãã«ã®é«æ§èœç·åœ¢ä»£æ°ã©ã€ãã©ãªã䜿çšããŠæçµçã«å®è¡ãããŸãã ããããæ®å¿µãªãããããã¯æãäžè¬çãªæäœã«ã®ã¿åœãŠã¯ãŸããäžè¬çãªã±ãŒã¹ã§ã¯æ©èœããŸããã æ®å¿µãªããããã¹ãã¿ã¹ã¯ã¯é 次å®è¡ãããŸãã
ãœãªã¥ãŒã·ã§ã³ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
def spnpGetR(p, q): Rx = p[:, 0:1] - q[0:1] Ry = p[:, 1:2] - q[1:2] Rz = p[:, 2:3] - q[2:3] R = 1 / (1 + np.sqrt(Rx * Rx + Ry * Ry + Rz * Rz)) return R
ããã4è¡ã§ãµã€ã¯ã«ãªãïŒ ã ããç§ã¯NumPyã倧奜ãã§ãã
çµæïŒ
ãŠãããã»ããµNumPy | 973ããªç§ |
ãŠãããã»ããµC ++ãããçŽ4.3åé
ãã ããã¯ãã§ã«ããªãè¯ãçµæã§ãã 倧åã®èšç®ã§ã¯ããã®ããã©ãŒãã³ã¹ã§ååã§ãã ãããããããã¯ãã¹ãŠãããŸã§ã®ãšãããŠãããã»ããµã®çµæã§ãã ãã«ãããã»ãã·ã³ã°ã«ç§»ããŸãããã
3ãã«ãããã»ããµNumPy
GILã®åé¡ã®è§£æ±ºçãšããŠãåŸæ¥ãè€æ°ã®å®è¡ã¹ã¬ããã®ä»£ããã«è€æ°ã®ç¬ç«ããå®è¡ããã»ã¹ã䜿çšããããšãææ¡ãããŠããŸãã ãã¹ãŠåé¡ãããŸããããåé¡ããããŸãã åããã»ã¹ã«ã¯ç¬ç«ããã¡ã¢ãªããããçµæã®ãããªãã¯ã¹ãåããã»ã¹ã«è»¢éããå¿
èŠããããŸãã ãã®åé¡ã解決ããããã«ãPythonãã«ãããã»ãã·ã³ã°ã¯RawArrayã¯ã©ã¹ãå°å
¥ããããã»ã¹éã§åäžã®ããŒã¿é
åãåå²ããæ©èœãæäŸããŸãã RawArrayã®åºç€ã¯æ£ç¢ºã«ã¯ããããŸããã ãããã¯ã¡ã¢ãªã«ãããããããã¡ã€ã«ã®ããã§ãã
ãœãªã¥ãŒã·ã§ã³ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
def mpnpGetR_worker(job): start, stop = job p = np.reshape(np.frombuffer(mp_share.p), (-1, 3)) q = np.reshape(np.frombuffer(mp_share.q), (3, -1)) R = np.reshape(np.frombuffer(mp_share.R), (p.shape[0], q.shape[1])) Rx = p[start:stop, 0:1] - q[0:1] Ry = p[start:stop, 1:2] - q[1:2] Rz = p[start:stop, 2:3] - q[2:3] R[start:stop, :] = 1 / (1 + np.sqrt(Rx * Rx + Ry * Ry + Rz * Rz)) def mpnpGetR(p, q): nP, nQ = p.shape[0], q.shape[1] sh_p = mp.RawArray(ctypes.c_double, p.ravel()) sh_q = mp.RawArray(ctypes.c_double, q.ravel()) sh_R = mp.RawArray(ctypes.c_double, nP * nQ) nCPU = 4 jobs = utils.generateJobs(nP, nCPU) pool = mp.Pool(processes=nCPU, initializer=mp_init, initargs=(sh_p, sh_q, sh_R)) pool.map(mpnpGetR_worker, jobs, chunksize=1) R = np.reshape(np.frombuffer(sh_R), (nP, nQ)) return R
å
¥åããŒã¿ãšåºåãããªãã¯ã¹çšã«åå²ãããé
åãäœæããã³ã¢ã®æ°ã«å¿ããŠããã»ã¹ã®ããŒã«ãäœæããã¿ã¹ã¯ããµãã¿ã¹ã¯ã«åå²ãã䞊è¡ããŠè§£æ±ºããŸãã
çµæïŒ
ãã«ãããã»ããµnumpy | 795ããªç§ |
ã¯ãããŠãããã»ããµããŒãžã§ã³ãããé«éã§ãããããã1.22åã§ãã æ°
Nãå¢å ãããšããœãªã¥ãŒã·ã§ã³ã®å¹çãåäžããŸãã ããããå
šäœãšããŠããããŠäžè¬çã«ãç§ãã¡ã®ãã¹ãã¿ã¹ã¯ã¯ãç¬ç«ããã¡ã¢ãªãåããå€ãã®ç¬ç«ããããã»ã¹ã®ãã¬ãŒã ã¯ãŒã¯å
ã§ã®è§£æ±ºã«ããŸãé©å¿ããŠããŸããã ä»ã®ã¿ã¹ã¯ã®å Žåããã®ãªãã·ã§ã³ã¯éåžžã«å¹æçã§ãã
ããã§ãPythonã ãã䜿çšããŠç§ã«ç¥ãããŠãã䞊åããã°ã©ãã³ã°ã®ãœãªã¥ãŒã·ã§ã³ã¯çµäºããŸããã ããã«ãGILãåãé€ãã«ã¯ãC ++ã¬ãã«ãŸã§äžããå¿
èŠããããŸãã ããããããã¯èŠãç®ã»ã©æããªãã
4ã·ãã³
Cython [3]ã¯ãPythonã³ãŒãã«Cåœä»€ãåã蟌ãããšãã§ããPythonæ¡åŒµã§ãã ãããã£ãŠãPythonã³ãŒããååŸããããã€ãã®åœä»€ã远å ããŠãããã©ãŒãã³ã¹ã®ããã«ããã¯ã倧å¹
ã«ã¹ããŒãã¢ããã§ããŸãã Cythonã¢ãžã¥ãŒã«ã¯Cã³ãŒãã«å€æãããPythonã¢ãžã¥ãŒã«ã«ã³ã³ãã€ã«ãããŸãã Cythonã§åé¡ã解決ããããã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
ãŠãããã»ããµCythonïŒ
@cython.boundscheck(False) @cython.wraparound(False) def spcyGetR(pp, pq): pR = np.empty((pp.shape[0], pq.shape[1])) cdef int i, j, k cdef int nP = pp.shape[0] cdef int nQ = pq.shape[1] cdef double[:, :] p = pp cdef double[:, :] q = pq cdef double[:, :] R = pR cdef double rx, ry, rz with nogil: for i in xrange(nP): for j in xrange(nQ): rx = p[i, 0] - q[0, j] ry = p[i, 1] - q[1, j] rz = p[i, 2] - q[2, j] R[i, j] = 1 / (1 + sqrt(rx * rx + ry * ry + rz * rz)) return R
ãã«ãããã»ããµCythonïŒ
@cython.boundscheck(False) @cython.wraparound(False) def mpcyGetR(pp, pq): pR = np.empty((pp.shape[0], pq.shape[1])) cdef int i, j, k cdef int nP = pp.shape[0] cdef int nQ = pq.shape[1] cdef double[:, :] p = pp cdef double[:, :] q = pq cdef double[:, :] R = pR cdef double rx, ry, rz with nogil, parallel(): for i in prange(nP, schedule='guided'): for j in xrange(nQ): rx = p[i, 0] - q[0, j] ry = p[i, 1] - q[1, j] rz = p[i, 2] - q[2, j] R[i, j] = 1 / (1 + sqrt(rx * rx + ry * ry + rz * rz)) return R
ãã®ã³ãŒããçŽç²ãªPythonå®è£
ãšæ¯èŒããå Žåã䜿çšãã倿°ã®åãæå®ããã ãã§æžã¿ãŸããã GILã¯1è¡ã§ãªãªãŒã¹ãããŸãã 䞊åã«ãŒãã¯ãxrangeã®ä»£ããã«prangeã¹ããŒãã¡ã³ãã«ãã£ãŠç·šæãããŸãã ç§ã®æèŠã§ã¯ãããã¯éåžžã«ã·ã³ãã«ã§çŸããã§ãïŒ
çµæïŒ
ãŠãããã»ããµCython | 255ããªç§ |
ãã«ãããã»ããµCython | 75ããªç§ |
ããïŒ ã©ã³ã¿ã€ã ã¯ãC ++ã®ã©ã³ã¿ã€ã ãšã»ãŒåãã§ãã é
å»¶ã¯ãå®éã®ã¿ã¹ã¯ã§ã¯ã»ãšãã©èªèã§ããªãã»ã©ããŠãããã»ããµããŒãžã§ã³ãšãã«ãããã»ããµããŒãžã§ã³ã®äž¡æ¹ã§çŽ1.1åã§ãã
5 numba
Numba [4]ã¯ããªãæ°ããã©ã€ãã©ãªã§ã掻çºã«éçºãããŠããŸãã ããã§ã®ã¢ã€ãã¢ã¯ãCythonãšã»ãŒåãã§ããPythonã³ãŒãã§C ++ã¬ãã«ã«å°éãã詊ã¿ã§ãã ããããã¢ã€ãã¢ã¯ã¯ããã«ãšã¬ã¬ã³ãã«å®è£
ãããŠããŸãã
Numbaã¯ãããã°ã©ã ã®å®è¡äžã«çŽæ¥ã³ã³ãã€ã«ïŒJITã³ã³ãã€ã«ïŒã§ããLLVMã³ã³ãã€ã©ã«åºã¥ããŠããŸãã ããšãã°ãPythonã§ããã·ãŒãžã£ãã³ã³ãã€ã«ããã«ã¯ãjitã¢ãããŒã·ã§ã³ã远å ããã ãã§ãã ããã«ã泚éã䜿çšãããšãå
¥å/åºåããŒã¿ã®ã¿ã€ããæå®ã§ãããããJITã³ã³ãã€ã«ã®å¹çã倧å¹
ã«åäžããŸãã
ã¿ã¹ã¯ãå®è£
ããããã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
ãŠãããã»ããµãã³ãïŒ
@jit(double[:, :](double[:, :], double[:, :])) def spnbGetR(p, q): nP = p.shape[0] nQ = q.shape[1] R = np.empty((nP, nQ)) for i in xrange(nP): for j in xrange(nQ): rx = p[i, 0] - q[0, j] ry = p[i, 1] - q[1, j] rz = p[i, 2] - q[2, j] R[i, j] = 1 / (1 + sqrt(rx * rx + ry * ry + rz * rz)) return R
ãã«ãããã»ããµNumbaïŒ
def makeWorker(): savethread = pythonapi.PyEval_SaveThread savethread.argtypes = [] savethread.restype = c_void_p restorethread = pythonapi.PyEval_RestoreThread restorethread.argtypes = [c_void_p] restorethread.restype = None def worker(p, q, R, job): threadstate = savethread() nQ = q.shape[1] for i in xrange(job[0], job[1]): for j in xrange(nQ): rx = p[i, 0] - q[0, j] ry = p[i, 1] - q[1, j] rz = p[i, 2] - q[2, j] R[i, j] = 1 / (1 + sqrt(rx * rx + ry * ry + rz * rz)) restorethread(threadstate) signature = void(double[:, :], double[:, :], double[:, :], int64[:]) worker_ext = jit(signature, nopython=True)(worker) return worker_ext def mpnbGetR(p, q): nP, nQ = p.shape[0], q.shape[1] R = np.empty((nP, nQ)) nCPU = utils.getCPUCount() jobs = utils.generateJobs(nP, nCPU) worker_ext = makeWorker() threads = [threading.Thread(target=worker_ext, args=(p, q, R, job)) for job in jobs] for thread in threads: thread.start() for thread in threads: thread.join() return R
çŽç²ãªPythonãšæ¯èŒããŠãNumbaã®ã·ã³ã°ã«ããã»ããµãœãªã¥ãŒã·ã§ã³ã«è¿œå ãããæ³šéã¯1ã€ã ãã§ãïŒ æ®å¿µãªããããã«ãããã»ããµããŒãžã§ã³ã¯ããã»ã©çŸãããããŸããã ã¹ã¬ããã®ããŒã«ãæŽçããGILãæåã§æäŸããå¿
èŠããããŸãã Numbaã®ä»¥åã®ãªãªãŒã¹ã§ã¯ãåäžã®åœä»€ã§äžŠåã«ãŒããå®è£
ããããšããŸããããåŸç¶ã®ãªãªãŒã¹ã®å®å®æ§ã®åé¡ã«ããããã®æ©èœã¯åé€ãããŸããã æéãçµã€ã«ã€ããŠããã®æ©äŒã¯ä¿®åŸ©ããããšç¢ºä¿¡ããŠããŸãã
å®è¡çµæïŒ
ãŠãããã»ããµãã³ã | 359ããªç§ |
ãã«ãããã»ããµnumba | 180ããªç§ |
Cythonããå°ãæªãã§ãããçµæã¯ãŸã éåžžã«ãŸãšãã§ãïŒ ãããŠããœãªã¥ãŒã·ã§ã³èªäœã¯éåžžã«ãšã¬ã¬ã³ãã§ãã
çµè«
çµæãæ¬¡ã®å³ã§èª¬æããŸãã
å³ 1.ãŠãããã»ããµã³ã³ãã¥ãŒãã£ã³ã°ã®çµæ
å³ 2.ãã«ãããã»ããµã³ã³ãã¥ãŒãã£ã³ã°ã®çµæ
Pythonã®æ°å€èšç®ã«é¢ããGILã®åé¡ã¯å®éã«å
æãããŠããããã«æããŸãã ãããŸã§ã®ãšããã䞊åã³ã³ãã¥ãŒãã£ã³ã°ãã¯ãããžãŒãšããŠCythonããå§ãããŸãã ããããç§ã¯æ¬åœã«NumbaãããèŠãŸãã
åç
§è³æ
[1]ç§åŠPythonïŒ
scipy.org[2]ãã¹ãã®å®å
šãªãœãŒã¹ã³ãŒãïŒ
github.com/alec-kalinin/open-nuance[3] CythonïŒ
cython.org[4] NumbaïŒ
numba.pydata.orgPSã³ã¡ã³ãã@chersayaãã¯ã䞊åã³ã³ãã¥ãŒãã£ã³ã°ã®å¥ã®æ¹æ³ãæ£ããææããŸããã ããã¯ãnumexprã©ã€ãã©ãªã®äœ¿çšã§ãã Numexprã¯ãCã§èšè¿°ãããç¬èªã®ä»®æ³ãã·ã³ãšç¬èªã®JITã³ã³ãã€ã©ã䜿çšããŸãã ããã«ããã圌ã¯åçŽãªæ°åŒãæååãšããŠååŸããã³ã³ãã€ã«ããŠãã°ããèšç®ããããšãã§ããŸãã
䜿çšäŸïŒ
import numpy as np import numexpr as ne a = np.arange(1e6) b = np.arange(1e6) result = ne.evaluate("sin(a) + arcsinh(a/b)")