当很难/不可能访问源时,我如何才能找出方法调用的时间复杂性



由于OOP在抽象实现方面非常巧妙,我仍然在问使用它时某个操作的时间复杂度是多少。

示例:集合文档。min

/**
 * Returns the minimum element of the given collection, according to the
 * <i>natural ordering</i> of its elements.  All elements in the
 * collection must implement the <tt>Comparable</tt> interface.
 * Furthermore, all elements in the collection must be <i>mutually
 * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
 * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
 * <tt>e2</tt> in the collection).<p>
 *
 * This method iterates over the entire collection, hence it requires
 * time proportional to the size of the collection.
 *
 * @param  <T> the class of the objects in the collection
 * @param  coll the collection whose minimum element is to be determined.
 * @return the minimum element of the given collection, according
 *         to the <i>natural ordering</i> of its elements.
 * @throws ClassCastException if the collection contains elements that are
 *         not <i>mutually comparable</i> (for example, strings and
 *         integers).
 * @throws NoSuchElementException if the collection is empty.
 * @see Comparable
 */

这是一个微不足道的例子,因为在查看源代码时很容易看到,但当实现更复杂或根本看不到时,就变得更难了。

我的问题:如何快速确定时间复杂性,以决定是否可行?尝试并出错?时间记录?

编辑:这不是最好的例子,因为它也写在文档中,但问题仍然存在:如果它不是用docu写的呢?

确定黑盒函数的时间复杂度显然是不可行的。复杂性是最坏情况下的定义。你可以有一个函数,对于大多数输入,它在线性时间内运行,但对于1000亿个输入中的1个,它会爆炸,需要数百万年的时间。没有办法排除这种可能性。

另一方面,如果你在给定大小的可能输入上有一个合理的概率分布,你可以使用统计方法来估计各种大小的平均时间复杂性,然后使用曲线拟合来得出一条启发式曲线来估计平均运行时间。

一个现实的例子。线性规划的单纯形算法在实践中运行非常快。但在20世纪70年代(通过精心构建的例子),它被证明具有指数级的时间复杂性。尽管如此,单纯形算法由于其良好的平均时间复杂度仍然被大量使用。从那时起,线性规划的多项式时间算法已经被发现并实现。如果你有一种解决线性规划问题的方法,那么可能没有简单的方法来知道它是实现指数时间单纯形算法还是最近的多项式时间算法之一。

(请注意,可能会对函数进行反编译,但在这种情况下,它不再是黑盒。)

最新更新