Чому java не використовує радіаційний сорт на примітивах?


12

java.util.Arrays.sort(/* int[], char[], short[], byte[], boolean[] */) реалізується як "настроєний кікспорт", а не як радіаційний сорт.

Я робив порівняння швидкості деякий час тому, і з чимось на зразок n> 10000, сортування в радіаку завжди було швидше. чому?

Відповіді:


17

Я б припускав, що:

  • Array.sort реалізований як quicksort, оскільки quicksort може сортувати що завгодно у гідний час за умови порівняння.
  • Сортування списку 10000 записів не так часто. Доступ до структури даних із 10000 і більше елементів є досить поширеним явищем. Якщо вам потрібно підтримувати порядок, збалансоване дерево пошуку часто є кращим способом, ніж сортування всього масиву щоразу, коли вам потрібен найменший елемент.
  • Сортування примітивів не так часто, незважаючи на те, що може викладати університет.

Справа в тому, що це не такий поширений випадок використання, що його оптимізація повинна бути в стандартній бібліотеці. Якщо ви написали заявку, яка має проблеми з продуктивністю, і за допомогою профілювання ви визначаєте, що сортування масиву 10000+ інт насправді є вузьким місцем, то ви можете також написати сортування вручну або переглянути свій вибір структури даних в першу чергу. місце.


Не на 100% впевнений, але, думаю, TimSort використовується в деяких випадках і зараз.
Мартійн Вербург

1
Але Array.sort не є чимось, є декілька Array.sorts, і питання про це було спеціалізовано для числових типів.
Дунайський матрос

6

Back2dos все це сказав, я просто спробую додатково уточнити точку, яка, на мою думку, є найбільш важливою:

Сортування Radix може лише сортувати фактичні примітивні значення, які містяться в масиві, виходячи з їх двійкових цифр. У реальних сценаріях інженерної розробки програмного забезпечення в реальному світі цей випадок не зустрічається майже ніколи . Те, що ми, як правило, робимо набагато частіше, це сортування масивів складніших (непомітних) структур даних, а іноді ми сортуємо масиви індексів до інших сутностей.

Тепер масив індексів для інших об'єктів насправді є масивом примітивів, але порядок сортування забезпечує інтерфейс порівняння (та / або делегат у C #), який порівнює не індекси, а сутності, індексовані індексами. Таким чином, порядок сортування абсолютно не має відношення до порядку значень примітивів, і тому сортинг radix абсолютно марний для цього сценарію.

Приклад:

У нас є масив рядків: [0] = "Майк", [1] = "Альберт", [2] = "Зоро". Тоді ми оголошуємо масив індексів до цих рядків: [0] = 0, [1] = 1, [2] = 2. Потім ми сортуємо масив індексів, передаючи йому компаратор, який порівнює не самі індекси, а фактичні рядки, на які посилаються ці індекси. Після сортування отриманий масив індексів виглядатиме так: [0] = 1, [1] = 0, [2] = 2. Як бачимо, цей порядок сортування не має нічого спільного з бінарними шаблонами значень, що містяться в масиві, і все ж, обходячи цей масив індексів і отримуючи кожний відповідний рядок, ми відвідуємо рядки в упорядкованому порядку.

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