размер пробега в Тимсорте - PullRequest
0 голосов
/ 26 февраля 2020

Я изучаю Timsort по этой ссылке hackernoon Timsort

Существует утверждение "Объединение двух массивов более эффективно, когда число прогонов равно или немного меньше, Степень двойки. Timsort выбирает minrun, чтобы попытаться обеспечить эту эффективность, убедившись, что minrun равен или меньше, чем степень двух. "

Почему" Объединение двух массивов более эффективно, когда число запусков равно или немного меньше, чем степень двух "?

1 Ответ

0 голосов
/ 02 марта 2020

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

В общем / случайном случае вы ожидаете произвести прогоны с точно minrun элементами. Затем, когда количество прогонов равно степени 2, вы получаете идеально сбалансированные слияния. Если количество прогонов немного больше , чем степень 2, вы получите очень несбалансированное слияние. Если количество прогонов немного меньше , чем степень 2, вы получаете лишь небольшой дисбаланс.

Опять же, это (по крайней мере, в основном) для общего / случайного случая. Например, если у вас есть девять естественных прогонов длиной 800, 100, 100, 100, 100, 100, 100, 100, 100, 100 элементов, то вы также получите идеально сбалансированные слияния, несмотря на то, что немного больше чем степень 2.

Выдержка из собственного описания Тима в listsort.txt относительно этого выбора minrun:

Because sortperf.py only tries powers of 2, it took a long time to notice
that 32 isn't a good choice for the general case!  Consider N=2112:

>>> divmod(2112, 32)
(66, 0)
>>>

If the data is randomly ordered, we're very likely to end up with 66 runs
each of length 32.  The first 64 of these trigger a sequence of perfectly
balanced merges (see next section), leaving runs of lengths 2048 and 64 to
merge at the end.  The adaptive gimmicks can do that with fewer than 2048+64
compares, but it's still more compares than necessary, and-- mergesort's
bugaboo relative to samplesort --a lot more data movement (O(N) copies just
to get 64 elements into place).

If we take minrun=33 in this case, then we're very likely to end up with 64
runs each of length 33, and then all merges are perfectly balanced.  Better!
...