Python:分数越大越慢?

时间:2016-08-19 13:29:39

标签: python performance

为什么除以较大的因子对会导致执行速度变慢?

我对https://codility.com/programmers/task/min_perimeter_rectangle/

的解决方案
from math import sqrt, floor

# This fails the performance tests
def solution_slow(n):
    x = int(sqrt(n))
    for i in xrange(x, n+1):
        if n % i == 0:
            return 2*(i + n / i))

# This passes the performance tests
def solution_fast(n):
    x = int(sqrt(n))
    for i in xrange(x, 0, -1):
        if n % i == 0:
            return 2*(i + n / i)

3 个答案:

答案 0 :(得分:3)

这不会减慢它的速度;这是所需的迭代次数。

L = xrange(0, x)(此处的顺序无关紧要)和R = xrange(x, n+1)nL的每个因素都可以与nR的一个因子配对。一般来说,x远远小于n/2,因此L远小于R。这意味着Rn的元素数量远不超过L中的<?php $child_page = 'https://www.google.com'; echo '<button type="button" class="btn btn-secondary" id="btn" style="margin-left:0%;color:gray" onclick="location.href=\'' . $child_page . '\'"> KEEP READING &nbsp;<span class="glyphicon glyphicon-chevron-right" style="color:gray"></span> </button>'; echo "<a href='$child_page'>Link </a>"; ?> 元素。在质数的情况下, 没有因子,因此缓慢的解决方案必须检查远大于而不是更小的集合的每个值。

答案 1 :(得分:1)

那很明显。第一个函数循环许多次。

请注意sqrt(n) != n - sqrt(n)!一般来说sqrt(n) << n-sqrt(n) <<表示小于。

如果n=1000第一个函数循环969次,而第二个函数仅32

答案 2 :(得分:0)

我认为迭代是关键,这使得你的功能之间的性能略有不同,正如@Bakuriu已经说过的那样。此外,xrange可能比使用简单的循环稍微贵一些,例如,看看f3会比f1&amp; F2:

import timeit
from math import sqrt, floor


def f1(n):
    x = int(sqrt(n))
    for i in xrange(x, n + 1):
        if n % i == 0:
            return 2 * (i + n / i)


def f2(n):
    x = int(sqrt(n))
    for i in xrange(x, 0, -1):
        if n % i == 0:
            return 2 * (i + n / i)


def f3(n):
    x = int(sqrt(n))

    while True:
        if n % x == 0:
            return 2 * (x + n / x)

        x -= 1


N = 30
K = 100000

print("Measuring {0} times f1({1})={2}".format(
    K, N, timeit.timeit('f1(N)', setup='from __main__ import f1, N', number=K)))
print("Measuring {0} times f1({1})={2}".format(
    K, N, timeit.timeit('f2(N)', setup='from __main__ import f2, N', number=K)))
print("Measuring {0} times f1({1})={2}".format(
    K, N, timeit.timeit('f3(N)', setup='from __main__ import f3, N', number=K)))

# Measuring 100000 times f1(30)=0.0738177938151
# Measuring 100000 times f1(30)=0.0753000788315
# Measuring 100000 times f1(30)=0.0503645315841
# [Finished in 0.3s]

下次,您有这类问题,强烈建议使用分析器:)