哪些程序/算法在运行时更改其数据结构的表示以获得更好的性能?
上下文 数据结构"定义"现实世界的概念是如何在计算机存储器中构建和表示的。对于不同类型的计算,应该/可以使用不同的数据结构来实现可接受的性能(例如,链表与阵列实现)。
自适应(参见自更新)数据结构是根据具体使用模式(例如,自平衡树)改变其内部状态的数据结构。这些变化是内部的,即取决于数据。此外,这些变化是通过设计预期的。
其他算法可以从表示的外部变化中受益。在 例如,矩阵乘法,它是一个众所周知的性能技巧来转置"第二个矩阵" (这样可以更有效地使用缓存)。这实际上是将矩阵表示从行主要顺序更改为列主要顺序。因为" A"与"转置(A)"不同,第二个矩阵在乘法后再次转置,以保持程序在语义上正确。
第二个例子是在程序启动时使用链表来填充数据结构"一旦列表的内容变为“稳定”,就改为基于数组的实现。
我正在寻找与其他示例程序具有类似经验的程序员,其中在其应用程序中执行外部表示更改以获得更好的性能。因此,数据结构的表示(选择的实现)在运行时作为程序的显式部分而改变。
答案 0 :(得分:4)
在许多情况下,出现了转换输入表示以便实现更高效算法的模式。我甚至可以说这是考虑设计高效算法的重要方法。想到的一些例子:
<强>堆排序即可。它的工作原理是将原始输入列表转换为二进制堆(可能是最小堆),然后重复调用remove-min函数以按排序顺序获取列表元素。渐渐地,它与最快的基于比较的排序算法相关联。
在列表中查找重复项。在不更改输入列表的情况下,这将花费O(n ^ 2)时间。但是,如果您可以对列表进行排序,或者将元素存储在哈希表或布隆过滤器中,则可以在O(n log n)时间内更好地找到所有重复项。
解决线性程序。线性程序(LP)是某种优化问题,在经济学和其他领域有许多应用。解决LP的最重要技术之一是 duality ,这意味着将原始LP转换为所谓的&#34; dual&#34;,然后解决双重问题。根据您的情况,解决双重问题可能比解决原始(&#34;原始&#34;)LP更容易。 This book chapter以一个很好的原始/双LP示例开始。
乘以非常大的整数或多项式。最快的已知方法是使用FFT;有关一些不错的说明,请参阅here或here。该想法的要点是将多项式的通常表示(系数列表)转换为评估基础(在某些精心选择的点处对该多项式的评估列表)。评估基础使得乘法变得微不足道 - 您可以将每对评估相乘。现在,您在评估的基础上得到了产品多项式,并且插入(与评估相反)以获取系数,就像您想要的那样。快速傅里叶变换(FFT)是一种非常有效的评估和插值步骤,整个过程比直接使用系数要快得多。
最常见的子字符串。如果要查找出现在一堆文本文档中的最长子字符串,最快的方法之一是从每个文本文档创建一个suffix tree,然后将它们合并在一起找到最深的公共节点。
线性代数。通过将原始矩阵转换为规范形式(例如Hermite normal form或计算QR factorization),可以最有效地执行各种矩阵计算。矩阵的这些替代表示使标准事物如计算逆,行列式或特征值的速度更快。
除了这些之外肯定有很多例子,但我试图提出一些变化。