Алгоритм KMP имеет две фазы: сначала он строит таблицу, а затем выполняет поиск, направленный по содержимому таблицы.
Наивный алгоритм имеет одну фазу: он выполняет поиск.Это делает поиск намного менее эффективным в худшем случае , чем этап поиска KMP.
Если KMP медленнее, чем простой алгоритм, то это , вероятно, , потому что сборкатаблица занимает больше времени, чем просто наивный поиск строки.Наивное сопоставление строк обычно очень быстро на коротких строках.Есть причина, по которой мы не используем алгоритмы, такие как KMP, в реализациях поиска строк BCL.К тому времени, когда вы настроите таблицу, вы могли бы выполнить полдюжины поисков коротких строк с помощью наивного алгоритма.
KMP - это только выигрыш, если у вас есть огромные строки и вы лотов поисков, которые позволяют вам повторно использовать уже построенную таблицу.Вы должны амортизировать огромные затраты на создание таблицы, выполняя множество запросов с использованием этой таблицы.
А также, наивный алгоритм имеет плохую производительность только в причудливых и маловероятных сценариях.Большинство людей ищут слова типа «Лондон» в строках, таких как «Букингемский дворец, Лондон, Англия», и не ищут слов типа «БАНАНАНАНАНАНА» в таких строках, как «БАНАН БАНБАН БАНБАНАНА БАНАН БАНАН БАНАНАНАНАНАНАН ...»Наивный алгоритм поиска является оптимальным для первой задачи и весьма неоптимальным для последней;но имеет смысл оптимизировать для первого, а не второго.
Другой способ выразить это: если искомая строка имеет длину w, а искомая строка имеет длину n, тогда KMPO (n) + O (w).Наивный алгоритм - худший случай O (nw), лучший случай O (n + w).Но это ничего не говорит о «постоянном факторе»!Постоянный коэффициент алгоритма KMP намного больше, чем постоянный коэффициент наивного алгоритма.Значение n должно быть ужасно большим, а количество неоптимальных частичных совпадений должно быть ужасно большим, чтобы алгоритм KMP одержал победу над невероятно быстрым наивным алгоритмом.
Это касается алгоритмической сложностипроблемы.Ваша методология также не очень хороша, и это может объяснить ваши результаты.Помните, что первый первый раз, когда вы запускаете код, джиттер должен вставить IL в код сборки. В некоторых случаях это может занять больше времени, чем запуск метода .Вы действительно должны выполнить код несколько сотен тысяч раз в цикле, отбрасывая первый результат и взяв среднее время остальных.
Если вы действительно хотите знать, что происходит, вы должны использовать профилировщик, чтобы определить, что такое горячая точка.Опять же, убедитесь, что вы измеряете прогон пост-JIT, а не прогон, в котором происходит сопряжение кода, если вы хотите, чтобы результаты не были искажены временем Jit.