建议为类型化的内存视图分配内存的方法是什么?

建议为类型化的内存视图分配内存的方法是什么?,第1张

建议为类型化的内存视图分配内存的方法是什么?

看看这里的回答。

基本思想是您想要

cpython.array.array
cpython.array.clone
不是
cython.array.*
):

from cpython.array cimport array, clone# This type is what you want and can be cast to things of# the "double[:]" syntax, so no problems therecdef array[double] armv, templatemvtemplatemv = array('d')# This is fastarmv = clone(templatemv, L, False)

编辑

事实证明,该线程中的基准是垃圾。这是我的设定,以及我的时间安排:

# cython: language_level=3# cython: boundscheck=False# cython: wraparound=Falseimport timeimport sysfrom cpython.array cimport array, clonefrom cython.view cimport array as cvarrayfrom libc.stdlib cimport malloc, freeimport numpy as numpycimport numpy as numpycdef int loopsdef timefunc(name):    def timedecorator(f):        cdef int L, i        print("Running", name)        for L in [1, 10, 100, 1000, 10000, 100000, 1000000]: start = time.clock() f(L) end = time.clock() print(format((end-start) / loops * 1e6, "2f"), end=" ") sys.stdout.flush()        print("μs")    return timedecoratorprint()print("INITIALISATIONS")loops = 100000@timefunc("cpython.array buffer")def _(int L):    cdef int i    cdef array[double] arr, template = array('d')    for i in range(loops):        arr = clone(template, L, False)    # Prevents dead pre elimination    str(arr[0])@timefunc("cpython.array memoryview")def _(int L):    cdef int i    cdef double[::1] arr    cdef array template = array('d')    for i in range(loops):        arr = clone(template, L, False)    # Prevents dead pre elimination    str(arr[0])@timefunc("cpython.array raw C type")def _(int L):    cdef int i    cdef array arr, template = array('d')    for i in range(loops):        arr = clone(template, L, False)    # Prevents dead pre elimination    str(arr[0])@timefunc("numpy.empty_like memoryview")def _(int L):    cdef int i    cdef double[::1] arr    template = numpy.empty((L,), dtype='double')    for i in range(loops):        arr = numpy.empty_like(template)    # Prevents dead pre elimination    str(arr[0])@timefunc("malloc")def _(int L):    cdef int i    cdef double* arrptr    for i in range(loops):        arrptr = <double*> malloc(sizeof(double) * L)        free(arrptr)    # Prevents dead pre elimination    str(arrptr[0])@timefunc("malloc memoryview")def _(int L):    cdef int i    cdef double* arrptr    cdef double[::1] arr    for i in range(loops):        arrptr = <double*> malloc(sizeof(double) * L)        arr = <double[:L]>arrptr        free(arrptr)    # Prevents dead pre elimination    str(arr[0])@timefunc("cvarray memoryview")def _(int L):    cdef int i    cdef double[::1] arr    for i in range(loops):        arr = cvarray((L,),sizeof(double),'d')    # Prevents dead pre elimination    str(arr[0])print()print("ITERATING")loops = 1000@timefunc("cpython.array buffer")def _(int L):    cdef int i    cdef array[double] arr = clone(array('d'), L, False)    cdef double d    for i in range(loops):        for i in range(L): d = arr[i]    # Prevents dead-pre elimination    str(d)@timefunc("cpython.array memoryview")def _(int L):    cdef int i    cdef double[::1] arr = clone(array('d'), L, False)    cdef double d    for i in range(loops):        for i in range(L): d = arr[i]    # Prevents dead-pre elimination    str(d)@timefunc("cpython.array raw C type")def _(int L):    cdef int i    cdef array arr = clone(array('d'), L, False)    cdef double d    for i in range(loops):        for i in range(L): d = arr[i]    # Prevents dead-pre elimination    str(d)@timefunc("numpy.empty_like memoryview")def _(int L):    cdef int i    cdef double[::1] arr = numpy.empty((L,), dtype='double')    cdef double d    for i in range(loops):        for i in range(L): d = arr[i]    # Prevents dead-pre elimination    str(d)@timefunc("malloc")def _(int L):    cdef int i    cdef double* arrptr = <double*> malloc(sizeof(double) * L)    cdef double d    for i in range(loops):        for i in range(L): d = arrptr[i]    free(arrptr)    # Prevents dead-pre elimination    str(d)@timefunc("malloc memoryview")def _(int L):    cdef int i    cdef double* arrptr = <double*> malloc(sizeof(double) * L)    cdef double[::1] arr = <double[:L]>arrptr    cdef double d    for i in range(loops):        for i in range(L): d = arr[i]    free(arrptr)    # Prevents dead-pre elimination    str(d)@timefunc("cvarray memoryview")def _(int L):    cdef int i    cdef double[::1] arr = cvarray((L,),sizeof(double),'d')    cdef double d    for i in range(loops):        for i in range(L): d = arr[i]    # Prevents dead-pre elimination    str(d)

输出:

INITIALISATIonSRunning cpython.array buffer0.100040 0.097140 0.133110 0.121820 0.131630 0.108420 0.112160 μsRunning cpython.array memoryview0.339480 0.333240 0.378790 0.445720 0.449800 0.414280 0.414060 μsRunning cpython.array raw C type0.048270 0.049250 0.069770 0.074140 0.076300 0.060980 0.060270 μsRunning numpy.empty_like memoryview1.006200 1.012160 1.128540 1.212350 1.250270 1.235710 1.241050 μsRunning malloc0.021850 0.022430 0.037240 0.046260 0.039570 0.043690 0.030720 μsRunning malloc memoryview1.640200 1.648000 1.681310 1.769610 1.755540 1.804950 1.758150 μsRunning cvarray memoryview1.332330 1.353910 1.358160 1.481150 1.517690 1.485600 1.490790 μsITERATINGRunning cpython.array buffer0.010000 0.027000 0.091000 0.669000 6.314000 64.389000 635.171000 μsRunning cpython.array memoryview0.013000 0.015000 0.058000 0.354000 3.186000 33.062000 338.300000 μsRunning cpython.array raw C type0.014000 0.146000 0.979000 9.501000 94.160000 916.073000 9287.079000 μsRunning numpy.empty_like memoryview0.042000 0.020000 0.057000 0.352000 3.193000 34.474000 333.089000 μsRunning malloc0.002000 0.004000 0.064000 0.367000 3.599000 32.712000 323.858000 μsRunning malloc memoryview0.019000 0.032000 0.070000 0.356000 3.194000 32.100000 327.929000 μsRunning cvarray memoryview0.014000 0.026000 0.063000 0.351000 3.209000 32.013000 327.890000 μs

(之所以使用“迭代”基准,是因为某些方法在这方面具有令人惊讶的不同特征。)

按照初始化速度的顺序:

malloc
:这是一个严酷的世界,但是很快。如果您需要分配很多东西并且具有不受阻碍的迭代和索引性能,那就必须如此。但是通常来说,您是一个不错的选择。

cpython.array raw Ctype
:该死,很快。而且很安全。不幸的是,它通过Python来访问其数据字段。您可以使用一个绝妙的技巧来避免这种情况:

arr.data.as_doubles[i]

从而在确保安全的同时使其达到标准速度!这使它成为的 绝妙 替代品

malloc
,基本上是一个参考计数很高的版本!

cpython.arraybuffer
:进入的时间只有的三到四倍
malloc
,这似乎是一个不错的选择。不幸的是,它具有大量的开销(尽管与
boundscheck
and
wraparound
指令相比很小)。这意味着它实际上只能与完全安全的变体竞争,但它
初始化速度最快的变体。你的选择。

cpython.arraymemoryview
:这比
malloc
初始化要慢一个数量级。太可惜了,但是迭代的速度一样快。这是我建议的标准解决方案,除非
boundscheck
wraparound
启用(在这种情况下,
cpython.arraybuffer
可能是更引人注目的折衷方案)。

其余的部分。

numpy
由于对象具有许多有趣的方法,因此唯一有价值的东西是。就是这样。



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5666167.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存