Обновить

Комментарии 6

std::nth_element ?

std::nth_element даёт топ-K неотсортированным за O(N) в среднем. GameBudget.Net даёт топ-K отсортированным за O(N log K) с SIMD-скорингом и групповыми квотами. Разные инструменты для разных задач. Если вам нужна только partition — nth_element подойдёт. Если нужна сортировка, групповые квоты и SIMD — GameBudget.Net. Ну и для .NET-проектов нативная C++ библиотека создаёт проблемы с P/Invoke и маршалингом.

Теоретически полный heap даёт меньше сравнений (O(N + K log N) против O(N log K)). На практике при малых K (100–2000) и больших N (100k+) разница незначительна, а полный heap требует O(N) дополнительной памяти и часто копирования исходных данных. В наших бенчмарках разница ~0.1 мс, но память экономится в 100 раз. Для групповых квот с per-group heaps разница ещё меньше. SIMD dot, а не селекция, является узким местом — 70–80% времени. Поэтому выбрали более экономный по памяти и аллокациям подход.

Вообще, с минихипом интересное решение. Там по ходу работы нужные элементы накапливаются и глубина проверки в куче всё меньше становится. А ближе к концу для большинства элементов в кучу совсем заглядывать не надо.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации