【问题标题】:Rough estimate of running time from Big OBig O 对运行时间的粗略估计
【发布时间】:2015-06-03 11:49:28
【问题描述】:

如果我的程序的时间复杂度是,比如说O(n^2),我该如何表达 对于较大的 n,10^6 值,运行时间以秒为单位

我需要对此进行粗略估计才能知道是否需要优化或者我可以 继续我的代码....时间限制是 0.6 秒

问题不是关于时间复杂度的计算......而是关于从时间复杂度中估计运行时间

【问题讨论】:

  • 无法使用大 O 表示法估算执行时间
  • @rsd_unleashed 你应该执行并测量时间并优化
  • 大 O 表示法告诉您代码如何扩展,而不是需要多长时间。也就是说,一个 O(n^2) 算法将花费 4 倍的时间来完成一个 n 是两倍大的问题。它没有告诉您任何关于给定 n 需要多长时间的信息,因为涉及的其他因素太多​​。除了创建一个测试用例并自己测量之外,没有办法确定需要多长时间。
  • 复杂度是根据程序的操作步骤来定义的。 stepstep (以及整个程序)可能需要完成的实际秒数之间没有关系(加起来,BigO 忽略 constants 和低阶 步骤)。实际执行取决于许多因素,例如 CPU 速度、CPU 内核数量、程序的性质(例如 IO 密集型或 CPU 密集型)。

标签: algorithm big-o time-complexity


【解决方案1】:

没有办法根据其 Big-O 评级来计算或估计某段代码的运行时间。

Big-O 告诉您一个方法在 要执行的操作方面如何扩展。它不知道执行一项操作需要多长时间。此外,CPU 在并行执行某些操作方面可能有好有坏,这使其更加困难。

唯一判断您是否存在性能瓶颈的方法是执行以下操作:

  1. 观察运行的代码。会不会太久?
  2. 测量正在运行的代码。会不会太久?
  3. 缩小测量范围,直到您知道代码的哪一部分是主要瓶颈。
  4. 决定它是否可以改变,你会摆脱它吗?

如果您还知道该代码的 Big-O 等级,您可以使用它来确定瓶颈是否会以指数方式恶化,例如,如果您将要处理的项目数量加倍。

【讨论】:

    【解决方案2】:

    您需要大致了解一项基本任务需要多少时间才能估计不同算法的运行任务。

    举个例子,假设你的基本任务是

    void func(){sleep(1)};
    

    现在您知道 O(1) 复杂度算法将只产生一次对 func() 的调用,这将花费 1 秒。

    查看其他示例:

    O(1) -> 1 * 1s
    O(N) -> N * 1s
    O(N2) -> (N^2) * 1s
    

    如果没有对任务执行时间的粗略估计,就不可能给出准确的答案。

    【讨论】:

      【解决方案3】:

      获得运行时间的最简单方法是使用给定的n 对您的算法进行基准测试(运行多次并使用平均值)。如果时间比您为估计运行时间分配的时间长,那么您需要进行近似。

      您可以使用以下公式获得具有O(n^x)(多项式)复杂度的算法的确切运行时间:c_x * n^x + c_x-1 * n^(x-1) ... + c_1 * n + c_0 其中乘数c_x ... c_0 可以是任何值。它们取决于算法的细节、您的 CPU、调度程序状态以及许多其他因素。

      您可以通过运行代码来估算这些乘数,该值足够小,不会占用您为估算和创建统计信息分配的更多时间。您可以使用多项式回归模型来估计乘数。通过估计,您可以将乘数应用于上述公式,以使用任何 n 值来近似运行时间。估计的准确性取决于您收集了多少统计信息,以及与用于统计信息的 n 的值相比,您估计的 n 大多少以​​及复杂度的顺序(高于二次方可能不会非常有用)。

      多项式回归方法本身超出了这个问题的范围。我建议为此阅读一本统计教科书。这是tutorial

      当然,您必须了解,这些测量和估计仅适用于您的您的硬件上运行的算法的实现,不能与其他硬件上的其他算法或测量。

      【讨论】:

        【解决方案4】:

        Big O 已经很粗糙了。尽管如此,这意味着您将执行大约 10^12 次或一万亿次迭代。

        例如,i7 4770K 在 3.9 GHz 下每秒有 1272.73 亿条指令。这通常是一个非常没有意义的指标,但由于我们这样做非常粗略,因此必须这样做。

        每次迭代一条指令,显然需要大约 8 秒才能完成。

        实际上,每次迭代可能需要几条指令,但迭代次数也可能更少(例如 n/2)。如果你给我们一个示例代码,我可以得到一个更好的猜测。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-21
          • 2020-01-23
          • 1970-01-01
          • 1970-01-01
          • 2010-11-06
          • 2018-08-26
          • 2021-09-05
          • 1970-01-01
          相关资源
          最近更新 更多