【问题标题】:Time Comp: Why is a single for loop with three assignment statements twice as fast as three sequential for loops each with one assignment statement?Time Comp:为什么包含三个赋值语句的单个 for 循环的速度是每个包含一个赋值语句的三个连续 for 循环的两倍?
【发布时间】:2023-03-25 14:20:01
【问题描述】:

为什么 try1 的速度是 try2 的两倍?这些函数不都是 O(n) 吗?执行时间的差异仅仅是由于开销吗?

我是编程新手,正在通过 Python 自学算法和数据结构。

根据我下面的文字,第一个函数的时间复杂度应该是3n(三个代表三个赋值语句),第二个函数的时间复杂度是n + n + n,即3n。

我错过了什么?

def try1(n):
    start = time.time()
    for i in range(n):
        a = 1
        b = 2
        c = 3

    end = time.time()
    return c,end-start

def try2(n):
    start = time.time()
    for i in range(n):
        a = 1
    for i in range(n):
        b = 2
    for i in range(n):
        c = 3

    end = time.time()
    return c,end-start

【问题讨论】:

  • 两种方式的时间复杂度都是O(n),但是有不同的因素。 Python 代码不是使用优化编译器编译的,运行循环确实会产生一些开销。
  • 还请考虑您正在计算两个循环中的每个变量分配。但循环还包括对i 的变量赋值。第一个例子发生 n 次,第二个例子是 3*n 次。
  • 没有 O(3n) 这样的东西,它只是 O(n)。它告诉您给定算法的主导项是什么,因此您可以在这里粗略地考虑,对于较大的 n 值,时间将与 n 成正比 - 如果 n 加倍,则时间加倍。它什么也没说,也没有说明有效速度。对于一些小的 n 值,O(n^3) 算法可能比 O(log(n)) 算法快,我们只知道当 n 增长时,前者会在某个点变得慢得多。

标签: python time big-o complexity-theory


【解决方案1】:

(1) 如果 range(n) 实际上是在计算一个整数列表,那么您将执行 3 次而不是 1 次。 (2) 在第一个中,您将循环变量循环通过 n 个事物的列表一次,但在第二个中,您将循环变量通过 n 个事物的列表循环三次。

我想第二个永远不会比第一个快,并且在没有优化编译器的情况下,我希望第二个肯定比第一个慢。

你可以考虑试试这个实验:

start = time.time()
for i in range(1000000):
    for j in range(n):
        break
end = time.time()
return c,end-start

通过将时间除以一百万,您应该对调用 range(n) 的原始成本有一个很好的了解。如果这是您所看到的额外时间的最大份额(与额外遍历列表两次相比),我不会感到惊讶。

如果是这种情况,您还可以通过先计算 x = range(n) 然后使用 for i in x 三次来改进第二个示例。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多