我如何优化此代码?(Python)

时间:2018-08-05 19:10:19

标签: python optimization

这是欧拉计划网站的问题5。

def divisable_into_1to20(num):
    for i in range(11,21):
        if num % i != 0:
        return False
    return True 

for i in range(2520,10000000000):
    if divisable_into_1to20(i):
        print(i)
        break

需要140秒

2 个答案:

答案 0 :(得分:1)

比方说,您希望代码速度很快。我的建议是使用Cython。快速搜索其documentation可以告诉您许多高度优化代码的技巧:声明类型,并行化... ... Jupyter Notebook中的一个示例可能是:

    %%cython
    # distutils: language = c++
    cimport cython
    from libcpp cimport bool

    @cython.cdivision(True)
    cdef inline bool divisable_into_1to20(int num):
        cdef int i, a=11, b=21
        for i in range(a,b):
            if cython.cmod(num,i):
                return False
        return True 

    cpdef problem_5_proj_euler():
        cdef int num, k1=2520, k2=10000000000
        for num in range(k1,k2):
            if divisable_into_1to20(num):
                return num

原始解决方案在我的笔记本电脑上花费了 130秒。这需要 900ms

奖金:并行化!

有人可能会说:嘿!确保如果我们并行化,我们将获得更好的性能!。所以我尝试了:

    %%cython
    # distutils: language = c++
    cimport cython
    from cython.parallel import prange
    from libcpp cimport bool

    @cython.cdivision(True)
    cdef inline bool divisable_into_1to20(int num) nogil:
        cdef int i, a=11, b=21
        for i in range(a,b):
            if cython.cmod(num,i):
                return False
        return True 

    cpdef problem_5_proj_euler():
        cdef int final_num, num, k1=2520, k2=10000000000
        for num in prange(k1,k2, nogil=True):
            if divisable_into_1to20(num):
                break
        return num

令人惊讶的是,此解决方案花费了 1.9秒,是速度的两倍!考虑到任务的大小,并行化会导致创建线程和运行代码段的开销。

答案 1 :(得分:-1)

(几乎)最快的解决方案是:

print(5*7*9*11*13*16*17*19)

很容易看出一个数字可以被2到20之间的数字整除,并且前提是该数字是该数字的倍数。