Когда нотация Big-O терпит неудачу?

Каковы некоторые примеры, когда нотация Big-O [1] не работает на практике?

То есть: когда будет выполняться алгоритм алгоритма A с большим временем O, чтобы алгоритм A был быстрее алгоритма B, но на практике алгоритм B быстрее, когда вы его запускаете?

Чуть шире: когда теоретические предсказания о несоответствии производительности алгоритма наблюдаются во время работы? Предсказание не-Big-O может быть основано на среднем/ожидаемом числе вращений в дереве поиска или количестве сравнений в алгоритме сортировки, выраженном как фактор, умноженное на количество элементов.

Разъяснение

Несмотря на то, что некоторые ответы говорят, нотация Big-O предназначена для прогнозирования производительности алгоритма. Тем не менее, это инструмент недостаток: он говорит только об асимптотической производительности, и он размывает постоянные факторы. Он делает это по какой-то причине: он предназначен для прогнозирования алгоритмической производительности, независимо от того, на каком компьютере вы выполняете алгоритм.

Что я хочу знать, так это: когда проявляются недостатки этого инструмента? Я нашел примечание Big-O разумно полезным, но далеким от совершенства. Каковы подводные камни, краевые случаи, gotchas?

Пример того, что я ищу: запуск алгоритма кратчайшего пути Dijkstra с кучей Fibonacci вместо двоичной кучи, вы получаете O (m + n log n) время по сравнению с O ((m + n) log n), для n вершин и m ребер. Вы ожидали бы увеличения скорости от кучи Фибоначчи рано или поздно, но скорость роста никогда не была реализована в моих экспериментах.

(Экспериментальное доказательство, без доказательства, предполагает, что бинарные кучи, работающие на равномерно случайных весах краев, проводят время O (1), а не время O (log n), что один большой результат для экспериментов. Еще один, который сука считает - ожидаемое количество вызовов DecreaseKey).

[1] Действительно, это не обозначение, которое терпит неудачу, но концепции, обозначенные позицией, и теоретический подход к прогнозированию производительности алгоритма. </анти-педантство >

В принятом ответе:

Я принял ответ, чтобы выделить те ответы, на которые я надеялся. Много разных ответов, которые так же хороши, существуют:) Что мне нравится в ответе, так это то, что он предлагает общее правило, когда нотация Big-O "терпит неудачу" (когда кеш-промахи доминируют над временем выполнения), что также может увеличить понимание (в некотором смысле Я не уверен, как наилучшим образом выразить ATM).

Ответы

Ответ 1

В одной области, где Big O терпит неудачу, применяются шаблоны доступа к памяти. Big O только подсчитывает операции, которые необходимо выполнить - он не может отслеживать, если алгоритм приводит к большему количеству промахов в кеше или данных, которые необходимо загрузить с диска. При малых N эти эффекты будут преобладать. Например, линейный поиск по массиву из 100 целых чисел, вероятно, приведет к поиску через двоичное дерево из 100 целых чисел из-за доступа к памяти, хотя бинарное дерево, скорее всего, потребует меньше операций. Каждое дерево node приведет к промаху в кеше, тогда как линейный поиск будет в основном касаться кеша для каждого поиска.

Ответ 2

Это происходит не только в одном случае: когда люди пытаются использовать его для чего-то, для чего это не предназначено.

Он рассказывает вам, как алгоритм масштабируется. Это не говорит вам, насколько это быстро.

Нотация Big-O не говорит вам, какой алгоритм будет быстрее в любом конкретном случае. Он говорит только, что для достаточно большого ввода один будет быстрее другого.

Ответ 3

Когда N мало, доминирует постоянный коэффициент. Поиск элемента в массиве из пяти элементов, вероятно, быстрее, чем поиск его в хеш-таблице.

Ответ 4

Короткий ответ: когда n мало. Задача Traveling Salesman быстро решена, когда у вас есть только три адресата (однако поиск наименьшего числа в списке из триллиона элементов может длиться некоторое время, хотя это O (n).)

Ответ 5

канонический пример - Quicksort, худшее время O (n ^ 2), а Heapsort - O (n logn). на практике, однако, Quicksort обычно быстрее, чем Heapsort. Зачем? две причины:

  • каждая итерация в Quicksort намного проще, чем Heapsort. Более того, он легко оптимизируется с помощью простых стратегий кэширования.

  • худший случай очень трудно попасть.

Но IMHO, это вовсе не означает, что "большой O не удается". первый фактор (время итерации) легко включить в ваши оценки. в конце концов, большие числа O должны быть умножены на этот почти постоянный facto.

второй фактор тает, если вы получаете амортизированные цифры вместо среднего. Их сложнее оценить, но расскажите более полную историю.

Ответ 6

Big-O описывает эффективность/сложность алгоритма и не обязательно время выполнения реализации данного блока кода. Это не означает, что Big-O терпит неудачу. Это просто означает, что он не предназначен для прогнозирования времени выполнения.

Обратите внимание на этот вопрос для отличного определения Big-O.

Ответ 7

  • Для большинства алгоритмов существует "средний случай" и "наихудший случай". Если ваши данные обычно попадают в сценарий "наихудшего случая", возможно, что другой алгоритм, хотя теоретически менее эффективен в среднем случае, может оказаться более эффективным для ваших данных.

  • Некоторые алгоритмы также имеют лучшие случаи, которыми могут воспользоваться ваши данные. Например, некоторые алгоритмы сортировки имеют ужасную теоретическую эффективность, но на самом деле очень быстро, если данные уже отсортированы (или почти так). Другой алгоритм, в то время как теоретически быстрее в общем случае, не может воспользоваться тем фактом, что данные уже отсортированы и на практике хуже.

  • Для очень маленьких наборов данных иногда алгоритм, который имеет лучшую теоретическую эффективность, может фактически быть менее эффективным из-за большого значения "k".

Ответ 8

Один пример (который я не эксперт) заключается в том, что симплекс-алгоритмы для линейного программирования имеют экспоненциальную худшую сложность на произвольных входах, хотя они хорошо работают на практике. Интересным решением этого является рассмотрение "сглаженной сложности", которая сочетает наихудшие и средние характеристики, рассматривая небольшие случайные возмущения произвольных входных данных.

Spielman and Teng (2004) смогли показать, что симплекс-алгоритм с тенью-вершиной имеет полиномиальную сглаженную сложность.

Ответ 9

Это несколько зависит от того, что измеряет Big-O, - когда это сценарии с наихудшим сценарием, он обычно "терпит неудачу" в том, что производительность во время работы будет намного лучше, чем предлагает Big-O. Если это средний случай, то это может быть намного хуже.

Нотация Big-O обычно "терпит неудачу", если входные данные в алгоритм имеют некоторую предварительную информацию. Часто нотация Big-O относится к наихудшей сложности, которая часто случается, если данные либо полностью случайны, либо полностью неслучайны.

В качестве примера, если вы подаете данные в алгоритм, который профилирован, а большой-на основе рандомизированных данных, но ваши данные имеют очень четко определенную структуру, ваши результаты могут быть намного быстрее, чем ожидалось. В то же время, если вы измеряете среднюю сложность, и вы производите данные, которые были рандомизированы, алгоритм может работать намного хуже, чем ожидалось.

Ответ 10

  • Маленький N - И для сегодняшних компьютеров 100, вероятно, слишком малы, чтобы волноваться.
  • Скрытые множители - IE merge vs quick sort.
  • Патологические случаи. Опять же, слияние и быстрый

Ответ 11

Big O не говорит, например. что алгоритм A работает быстрее, чем алгоритм B. Можно сказать, что время или пространство, используемые алгоритмом A, растут с другой скоростью, чем алгоритм B, когда увеличивается вход. Однако для любого конкретного размера ввода большая нотация O не говорит ничего о производительности одного алгоритма относительно другого.

Например, A может быть медленнее для каждой операции, но имеет более высокий размер-O, чем B. B более эффективен для меньшего ввода, но если размер данных увеличивается, будет некоторая точка отсечения, где A становится быстрее, Big-O сам по себе ничего не говорит о том, где эта точка отсечения.

Ответ 12

Одна широкая область, где сбой Big-Oh, происходит, когда объем данных превышает доступный объем ОЗУ.

Используя сортировку в качестве примера, количество времени, которое требуется для сортировки, не зависит от количества сравнений или свопов (из которых в оптимальном случае есть O (n log n) и O (n)). Количество времени в нем зависит от количества операций с дисками: записи блоков и чтения блоков.

Чтобы лучше анализировать алгоритмы, которые обрабатывают данные, превышающие доступную оперативную память, родилась модель ввода-вывода, в которой вы подсчитываете количество чтений на диске. В этом случае вы учитываете три параметра:

  • Число элементов, N;
  • Объем памяти (ОЗУ), М (количество элементов, которые могут быть в памяти); и
  • Размер блока диска, B (количество элементов на блок).

Заметно отсутствует объем дискового пространства; это рассматривается как бесконечное. Типичным дополнительным предположением является то, что M > B 2.

Продолжая пример сортировки, вы обычно предпочитаете сортировку слияния в случае ввода-вывода: разделите элементы на куски размером θ (M) и отсортируйте их в памяти (например, с помощью быстрой сортировки). Затем объедините их (M/B), читая первый блок из каждого фрагмента в память, набивайте все элементы в кучу и повторно выбирайте наименьший элемент, пока не наберете B из них. Запишите этот новый блок слияния и продолжите. Если вы когда-либо исчерпали один из блоков, которые вы читали в память, прочитайте новый блок из того же фрагмента и поместите его в кучу.

(Все выражения должны быть считаны большими θ). Вы формируете N/M отсортированные куски, которые затем сливаете. Вы объединяете log (базовый M/B) из N/M раз; каждый раз, когда вы читаете и записываете все блоки N/B, так что вы берете N/B * (время регистрации базы M/B N/M).

Вы можете анализировать алгоритмы сортировки в памяти (соответственно модифицированные для включения блочных чтений и блочных записей) и видеть, что они намного менее эффективны, чем представленный мной тип слияния.

Это знание учтено моим курсом I/O-алгоритмов, Arge and Brodal (http://daimi.au.dk/~large/ioS08/); Я также провел эксперименты, которые подтверждают теорию: сортировка кучи принимает "почти бесконечное" время, как только вы превысите память. Быстрая сортировка становится невыносимо медленной, слияние сортируется с едва заметной медленностью, эффективная сортировка слияния/вывода эффективна (лучшая из группы).

Ответ 13

Общий ответ: Big-O позволяет вам быть неаккуратным, скрывая постоянные факторы. Как упоминалось в вопросе, использование кубов Фибоначчи является одним из примеров. Фибоначчи-кучи имеют большие асимптотические времена автономной работы, но на практике коэффициенты констант слишком велики, чтобы быть полезными для размеров наборов данных, встречающихся в реальной жизни.

Кубы Фибоначчи часто используются для доказательства хорошей нижней оценки асимптотической сложности алгоритмов, связанных с графом.

Другим аналогичным примером является алгоритм Coppersmith-Winograd для матричного умножения. В настоящее время это алгоритм с самым быстрым известным асимптотическим временем работы для матричного умножения, O (n 2.376). Однако его постоянный коэффициент слишком велик, чтобы быть полезным на практике. Подобно Fibonacci Heaps, он часто используется как строительный блок в других алгоритмах для доказательства теоретических временных ограничений.

Ответ 14

Я видел несколько случаев, когда, по мере роста набора данных, алгоритмическая сложность стала менее важной, чем шаблон доступа к памяти. Навигация в большой структуре данных с помощью интеллектуального алгоритма может в некоторых случаях приводить к большему количеству сбоев страницы или кэш-промахам, чем к алгоритму с худшим большим-O.

При малых n два алгоритма могут быть сопоставимыми. С ростом n более эффективный алгоритм превосходит. Но в какой-то момент n растет настолько, что система уступает давлению памяти, и в этом случае "худший" алгоритм может действительно работать лучше, потому что константы в основном reset.

Это не особенно интересно. К тому моменту, когда вы достигнете этой точки инверсии, производительность обоих алгоритмов обычно неприемлема, и вам нужно найти новый алгоритм, который имеет более дружелюбный шаблон доступа к памяти и лучшую сложность с большим O.

Ответ 15

Если ваши данные не соответствуют модели, нотация большого размера будет работать, но вы увидите перекрытие от лучших и наихудших сценариев.

Кроме того, некоторые операции настроены для линейного доступа к данным по сравнению случайного доступа к данным, поэтому один алгоритм, а выше в терминах циклов, может быть медленным, если упорно метод, назвав его изменения от дизайна. Аналогично, , если алгоритм вызывает пропуски страницы/кэша из-за того, как он обращается к памяти, Big-O не собирается точно оценивать стоимость запуска процесса.

По-видимому, как я и забыл, также , когда N мало:)

Ответ 16

Этот вопрос похож на вопрос: "Когда человек IQ терпит неудачу на практике?" Понятно, что высокий IQ не означает, что вы добьетесь успеха в жизни, а низкий IQ не означает, что вы погибнете. Тем не менее, мы измеряем IQ как средство оценки потенциала, даже если оно не является абсолютным.

В алгоритмах нотация Big-Oh дает вам алгоритм IQ. Это не обязательно означает, что алгоритм будет лучше всего работать в вашей конкретной ситуации, но есть математическая основа, которая говорит, что этот алгоритм имеет хороший потенциал. Если записей Big-Oh было достаточно, чтобы измерить производительность, вы бы увидели намного больше и меньше времени тестирования.

Подумайте о Big-Oh как о диапазоне, а не о конкретной мера лучше или хуже. Там лучшие сценарии и сценарии худшего случая и огромный набор сценариев между ними. Выбирайте свои алгоритмы, насколько хорошо они подходят в диапазоне Big-Oh, но не полагайтесь на обозначение как абсолютное значение для измерения производительности.

Ответ 17

Короткий ответ: всегда на современном оборудовании, когда вы начинаете использовать много памяти. Учебники предполагают, что доступ к памяти является единым, и его больше нет. Разумеется, вы можете провести большой анализ O для модели неравномерного доступа, но это несколько сложнее.

Маленькие n случаев очевидны, но не интересны: достаточно быстро достаточно быстро.

На практике у меня были проблемы с использованием стандартных коллекций в Delphi, Java, С# и Smalltalk с несколькими миллионами объектов. И с меньшими, где доминирующим фактором оказалась хэш-функция или сравнение

Ответ 18

Роберт Седжуик говорит о недостатках нотации большого О в своем курсе Курсера по анализу алгоритмов. Он называет особенно вопиющие примеры галактических алгоритмов, потому что, хотя они могут иметь более сложный класс, чем их предшественники, для этого на практике будут представлены данные астрономических размеров.

https://www.cs.princeton.edu/~rs/talks/AlgsMasses.pdf