没什么比对象模式慢吗?

2024-10-16 20:48:11 发布

您现在位置:Python中文网/ 问答频道 /正文

首先在这里使用Numba。我读到没有任何Python模式可以产生更快的代码,但是:

@jit(float64[:](int64[:], int64, float64), nopython=True)
def epsilon_bound(l, k, delta):
    return l/k+np.sqrt(np.log(1/delta))*np.sqrt(1/(2*k))

@jit(float64(float64, int64, float64), nopython=False)
def sim_bin(epsilon, sims, delta):
    k=10000
    s = np.random.binomial(k, epsilon, size=(sims,))
    print(nb.typeof(s))
    bound = epsilon_bound(s, k, delta)
    violations = np.greater(epsilon, bound)
    return np.sum(violations)/float(sims)

%%time
a = sim_bin(0.1, 1_000_000, 0.1)

运行速度更快:

^{pr2}$

比这更重要的是:

@jit(float64[:](int64[:], int64, float64), nopython=True)
def epsilon_bound(l, k, delta):
    return l/k+np.sqrt(np.log(1/delta))*np.sqrt(1/(2*k))

@jit(float64(float64, int64, float64), nopython=True)
def sim_bin(epsilon, sims, delta):
    k=10000
    s = np.random.binomial(k, epsilon, size=(sims,))
    #print(nb.typeof(s))
    bound = epsilon_bound(s, k, delta)
    violations = np.greater(epsilon, bound)
    return np.sum(violations)/float(sims)

CPU times: user 4.94 s, sys: 8.02 ms, total: 4.95 s
Wall time: 4.93 s

运行sim卡_箱子检查类型()显示第一个选项使用所有pyobjects,而第二个选项正确推断所有类型。根据文档(http://numba.pydata.org/numba-doc/0.31.0/glossary.html#term-nopython-mode),没有任何Python模式可以生成更快的代码。 有人知道发生了什么事吗?一定有一个很好的理由,但我对使用Numba还不熟悉。是因为我主要使用向量化的numpy函数吗?在

谢谢!!在


Tags: truereturndefnpsimsqrtjitdelta
1条回答
网友
1楼 · 发布于 2024-10-16 20:48:11

函数的一个主要瓶颈(至少在numba0.31,windows10中)似乎是np.random.binomial-调用。当我测试它时:

@jit(nopython=True)
def nbbinom():
    return np.random.binomial(10000, 0.1, size=(1000000,))

nbbinom() # warmup
%timeit nbbinom()
# 1 loop, best of 3: 2.45 s per loop
%timeit np.random.binomial(10000, 0.1, size=(1000000,))
# 10 loops, best of 3: 23.1 ms per loop

然而,这可能取决于numba版本。Numba(不幸的是)经常遭受性能衰退的困扰(幸运的是)很快就被修复了。可能它只需要他们的bug跟踪器上的一个问题(如果还没有修复的话)。在

但即便如此,你的代码也包含了大量的矢量化操作。如果使用矢量化操作,numba的速度提升不会太快。根据经验法则:如果您已经可以使用numpy而不使用python循环来完成它,则不需要numba(有例外情况。例如:我发现numba对于小型阵列来说确实更快,因为numpy ufunc有很大的开销)。在

另一件事是,创建随机数组所需的时间(在numpy和numba中)比实际操作要长得多:

^{pr2}$

因此,当您对sim_bin进行基准测试时,实际上只对np.random.binomial的调用进行基准测试,要么是相对快速的numpy-one,要么是(目前)相当慢的numba实现。在

相关问题 更多 >