Java та .NET: Чому різні алгоритми сортування використовуються за замовчуванням?


19

Цікаво, чому Javaі .NET Frameworkвикористовує різні алгоритми сортування за замовчуванням.

У Java Array.Sort() використовується алгоритм сортування об'єднань за замовчуванням і, як каже Wikipedia.com :

У Java методи Arrays.sort () використовують сортування злиття або відрегульований quicksort залежно від типів даних та для ефективності реалізації переходять на сортування вставки, коли сортується менше семи елементів масиву

У .NET Framework Array.Sort/List.Sort() використовується алгоритм сортування за замовчуванням ( MSDN ) Quick Sort :

List.Sort () використовує Array.Sort, який використовує алгоритм QuickSort. Ця реалізація виконує нестабільний сорт; тобто, якщо два елементи рівні, їх порядок може не зберігатися. На відміну від них, стабільний сорт зберігає порядок елементів, рівних.

Переглядаючи чудову таблицю "Порівняння алгоритмів", ми бачимо, що обидва алгоритми мають досить різну поведінку з точки зору використання гіршого випадку та використання пам'яті:

введіть тут опис зображення

І те, Javaі .NETінше є чудовими рамками для розвитку корпоративних рішень, обидва мають платформи для вбудованої розробки. То чому вони використовують різні алгоритми сортування за замовчуванням, будь-які думки?


1
Для подальшого обговорення порівняння між цими двома видами, см stackoverflow.com/q/680541/866022
yoozer8

Відповіді:


10

Настільки детермінований, як і самі комп’ютери, комп'ютерна інженерія не є точною наукою. Двоє людей, отримавши однакову проблематичну область, проведуть аналіз та розробити два різних рішення, які задовольняють усі обмеження проблеми. Емпірично визначити, що з них "краще" в загальному випадку, може бути важко або неможливо.

Я здогадуюсь, що .NET QuickSort нанесений поверх чогось у MFC або Windows API і, ймовірно, успадкований від набагато старих версій Windows, де багаторазова перевага MergeSort навіть не вважалася б для комп'ютерів день. ( EDIT: це не так, хоча розробники Microsoft вже тривалий час є фанатами QuickSort, про що свідчить такий вибір впорядкування сортування з часів MS-DOS).

Java, яка не може використовувати будь-яку платформу, тому що Java була розроблена з нуля, щоб бути абсолютно незалежною від платформи, пішла іншим шляхом. Хтозна, чому MergeSort вийшов зверху; моє дике здогадка полягає в тому, що реалізація виграла якусь конкуренцію за ефективність порівняно з деякими іншими видами, з якими розробники розробляли, або ж, що O (n) -простор MergeSort просто виглядав найкраще на папері з точки зору найкращої та найгіршої ефективності (У MergeSort немає п'яти Ахілла, що стосується вибору елементів, як QuickSort, і його найкращим випадком є ​​майже відсортований список, хоча це найгірше для QuickSort). Я сумніваюся, що переваги багатопотокової роботи спочатку розглядалися, але поточна реалізація цілком може бути багатопоточною.


1
List<T>.Sortв .NET використовує власний метод, реалізований у CLR (якщо ви не використовуєте користувацький порівняльник), але не має залежностей від бібліотек ОС.
Джої

1
@Keith - .NET не є багатошаровим і розроблений таким чином, щоб бути незалежним від платформи. Ви можете ознайомитись із реалізацією тут: github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/…
Роберт Маклін

@RobertMacLean - ".NET не нанесений поверх нічого" - це неправдиве твердження, хоча ви продемонстрували, що розглянутий функцією сортування є повністю "керований" код. Великі частини .NET, включаючи підтримку криптографії, бібліотеки графічного інтерфейсу Windows на робочому столі, інтероп API Windows (включаючи управління процесами та потоками), базуються на раніше існуючому некерованому коді, включаючи MFC. Вони просто повинні бути; Сама Windows має лише дуже незначний компонент .NET своєї кодової бази, решта - некерована
KeithS

Залишається, що розробники Майкрософт є перевіреними фанатами QuickSort над іншими реалізаціями, оскільки QuickSort був алгоритмом вибору з MS-DOS, і це вплинуло б на їхнє рішення впровадити сортування .NET за допомогою цього алгоритму.
KeithS

Ця відповідь така помилкова, що я чесно вражений.
user9993

17

Різні команди розробників у двох різних компаніях прийшли до різних висновків щодо звичайного випадку використання для їх рамок та компонентів, і вирішили відповідно впровадити їх.

По суті, кожна компанія робила свій аналіз, переглядала клієнтську базу і відповідно приймала різні рішення.

Ви не можете розраховувати на аналіз різних компаній та команд, використовуючи різні припущення та вихідні дані, щоб дійти одного і того ж висновку.


5
Або навіть однакові припущення та необроблені дані. . .
Wyatt Barnett

Так, це було, мабуть, лише силою звички - Microsoft звик використовувати (нестабільний) квакісорт, Java хотіла йти зі стабільним видом ... і сортування злиття було найшвидшим відомим стабільним ...
rogerdpack

12

Це питання трохи застаріло, оскільки Java зараз використовує Timsort (як у Java 7)

З зазначених алгоритмів:

  • Quicksort має несприятливі найгірші показники роботи при O (n ^ 2), але трохи легший / менш затратний на об'єм пам'яті, тому пропонує кращі показники в типовому випадку.

  • Mergesort гарантував найгірші показники продуктивності в O (n log n), але передбачає дещо більші накладні витрати та пам'ять. Він також автоматично стабільний (тобто підтримує рівні елементи в одному порядку).

Дизайнери Java здаються загалом більш консервативними / орієнтованими на "правильну річ", тому не дивно, що вони обрали Mergesort з двох, оскільки він пропонує кращі гарантії.

Не впевнені, чому Microsoft обрала Quicksort, можливо, вони хоч і змусили б їх виглядати краще в деяких мікропорівнях?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.