Data.ByteString.Char8中'isInfixOf'的时间复杂度是O(m*n)?

Data.ByteString.Char8中'isInfixOf'的时间复杂度是O(m*n)?,string,algorithm,haskell,String,Algorithm,Haskell,通过阅读相关的源代码 , 看来isInfix算法实际上是O(m*n)。但事实上,它比我自己的KMPcode运行得快得多 那么这个算法实际上是 o(m*n)< /代码>,而 Haskell < /C> >如何使这个函数极其有效?< P>渐近复杂度不考虑任何常量,这可能比现实本身更复杂。可能是这样的-它们有非常小的常数,你有大的常数 根据定义,更大的复杂性是,当一个函数在一个点上具有无穷大的值时,即使将其他函数乘以任何大小的常数 然而,“一点”可能是巨大的 例如,如果您有两个具有此运行时的ALGHO

通过阅读相关的源代码

,

看来
isInfix
算法实际上是
O(m*n)
。但事实上,它比我自己的
KMP
code运行得快得多


那么这个算法实际上是<代码> o(m*n)< /代码>,而 Haskell < /C> >如何使这个函数极其有效?

< P>渐近复杂度不考虑任何常量,这可能比现实本身更复杂。可能是这样的-它们有非常小的常数,你有大的常数

根据定义,更大的复杂性是,当一个函数在一个点上具有无穷大的值时,即使将其他函数乘以任何大小的常数

然而,“一点”可能是巨大的

例如,如果您有两个具有此运行时的ALGHORITM:
1000000*n*sqrt(n)
n^2
,则
n^2
的复杂性更大,但要实现第一个的更高速度,
n
必须高于
1 000
。对于较小的数字
n^2
alghoritms更快



<> P> >考虑代码>复杂性,但事实上,它比KMP代码运行得快得多,不是很好的方法。

渐近复杂性不考虑任何常量,它可能比现实本身更复杂。可能是这样的-它们有非常小的常数,而您有大的常数。但事实上,使用数据中的
isInfixOf
。列表将无法击败KMP算法。所以,似乎只有将字符串更改为ByteString才能极大地提高效率。这是为什么呢?例如,请注意,对于非退化数据,大多数
isPrefixOf
s将在前几个字符中失败,因此您将看到近似线性的性能。你可以设计一些会导致二次性能的东西,但这是非常特殊的,不是通常的情况。哦,
String
s是链表,就字符串表示而言,它们效率非常低
ByteString
在连续内存中每个字符保留一个字节有着巨大的实际优势。我想你只是看到了ByteString使用的更好的数据结构的效果。更少的内存流量和更好的局部性。至少有一种情况会导致二次时间复杂性,因为来自数据的
isInfixOf
。列表不能在5秒内完成,而KMP可以在0.26秒内完成。但是
Data.ByteString.Char8
中的
isInfixOf
可以在0.08秒内完成。因此,两个相同算法的效率至少相差60倍,只是表示结构不同。由于Data.List中的
isInfixOf
也非常简单,我相信它的算法复杂度常数也很小,这意味着从
[Char]
更改为
ByteString
将获得60倍以上的效率增益。