【问题标题】:Avoid loops in the computation of logistic equation?避免逻辑方程计算中的循环?
【发布时间】:2015-08-11 18:31:27
【问题描述】:

我正在尝试在 Python 中计算逻辑方程的第 n 个值。使用循环很容易做到这一点:

import timeit
tic = timeit.default_timer()

x = 0.23
i = 0
n = 1000000000
while (i < n):
    x = 4 * x * (1 - x)
    i += 1

toc = timeit.default_timer()
toc - tic

但是,它通常也很耗时。正如 abarnert 在 Is MATLAB faster than Python (little simple experiment) 中所建议的那样,在 PyPy 中执行此操作可大大提高性能。

我还被建议避免使用 Python 循环并改用 NumPy 数组和向量操作 - 实际上我看不出这些有什么帮助(在我看来,NumPy 操作类似于 Matlab 的操作,我不知道有任何上面的代码也可以在 Matlab 中进行矢量化)。

有没有办法在没有循环的情况下优化代码?

【问题讨论】:

    标签: performance python-3.x for-loop numpy vectorization


    【解决方案1】:

    没有循环?也许吧,但这可能不是最好的方法。重要的是要意识到循环本身并不慢。在高性能代码中,您尝试在 pythonmatlab 中避免它们。如果您正在编写C 代码,则不必关心。

    所以这里要优化的一个想法是使用cython 将您的代码编译为C 代码:

    python版本:

    def calc_x(x, n):
        i = 0
        while (i < n):
            x = 4 * x * (1 - x)
            i += 1
        return x
    

    静态类型cython 版本:

    def calc_x_cy(double x, long n):
        cdef long i = 0
        while (i < n):
            x = 4 * x * (1 - x)
            i += 1
        return x
    

    突然之间,你的速度几乎快了两个数量级:

    %timeit calc_x(0.23, n) -> 1 次循环,最好的 3 次:每次循环 26.9 秒

    %timeit calc_x_cy(0.23, n) -> 1 个循环,3 次中的最佳:每个循环 370 毫秒

    【讨论】:

    • 我还没有尝试过 Cython - 如果您的代码在 037 秒内运行,那似乎很有趣。我为 Matlab 编写了一个 mex 文件,令人惊讶的是,它比 Matlab 中的代码慢(!)。
    • 是的,Cython 或 Pypy 似乎是这里最简单的方法,因为您的循环无法矢量化。在您的计算机上尝试之前,您不能说它是否比 Matlab + .mex 慢,因为它取决于系统和编译器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 2016-03-20
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多