Русский
Русский
English
Статистика
Реклама

Нестабильная сортировка в JavaScript

Когда я вижу пост на подобную тему в любой социальной сети, под ним почти всегда оказывается множество комментов вот такого типа:

  • Зачем это нужно знать, если есть встроенные методы сортировки?

  • Зачем изобретать велосипед заново?

  • Это нужно, чтобы пройти собеседование, объективно больше незачем это знать

  • В "любой движок javascript" работают не дураки, и уже сделали все как нужно

И сам я раньше считал так же, пока не пришел в одну из команд Ростелеком ИТ frontend-разработчиком. Вместе мы набрели на очень интересный кейс: нужно было создать виджет, который мог бы встраиваться в информационные системы всех наших макрорегиональных филиалов и упрощать работу операторов по подбору оптимального тарифа.

Сразу к делу

Как думаете, что произойдет после выполнения данного кода?

Кажется, что ничего странного, но есть нюансы.

Случай номер раз

Сделали задачу, техническое решение, код, unit-тесты. По бизнес-процессу тоже все хорошо. При поверхностном тестировании проблем не нашли. Но когда дело дошло до авто-тестов, начались странности. Конфигурация, которую просчитывал Node.js 10, в основном отдавала корректный результат, но иногда конфигурация отличалась. Что усложняло процесс поиска проблемы, учитывая, что в режиме отладки конфигурация отдавалась всегда корректной. А еще у одних членов команды некорректная конфигурация воспроизводилась, а у других нет. И мы сделали вывод, что в старой версии, наверное, баг, и решили обновить версию на более новую.

После длительного поиска проблемы в коде ошибка не была найдена. Тестирование проекта на разных Node показало, что при запуске проекта на Node, начиная с версии 11, ответ был всегда стабильным. Что и послужило решением этой проблемы. Версия Node была обновлена до 12, и проблема исчезла.

Случай номер два

На этот раз конфигурации отличались уже в разных версиях браузера: в Google Chrome 80 был корректный результат, а в его 69 версии нет. И тут нам стало интересно, почему же конфигурация отличается.

  • Увидел, что версии отличаются

  • Открыл Release notes Google Chrome

  • Обнаружил, что Google Chrome 69 это последняя сборка, где используется 6-я версия V8

  • Открыл Release notes V8

  • И начал просматривать все статьи между 6 и 7 версией V8

Спустя некоторое время я наткнулся на статью Getting things sorted in V8, в которой говорится, что с 7-й версии V8 переходит на стабильный алгоритм сортировки TimSort, вместо предыдущего нестабильного QuickSort. И тут сразу стало понятно, что никакой магии нет, и все эти баги из-за нестабильной сортировки.

Нюансы сортировки

Сортировка в Node.js 10.22 (движок V8 v6.8) QuickSort.

Как видите, массив из первого скриншота изменил порядок, хотя функция сравнения всегда возвращала 0.

Сортировка в Node.js 14.5 (движок V8 v7.0) TimSort.

На этот раз сортировка уже не изменила данные.

Как дальше жить

И что же в итоге получается? То, что у клиентов могут быть разные результаты работы нашего кода в зависимости от типа сортировки используемого движка JavaScript. И если с Node.js переход на новую версию решит проблему, то заставить всех пользователей сделать то же самое со своими браузерами не получится.

Есть несколько разных решений, которые подойдут для конкретных кейсов. В нашем случае мы решили использовать реализацию алгоритма BlockSort (wikisort). Да, реализация работает медленнее, чем нативная сортировка браузера, но зато теперь я уверен в стабильности результата сортировки там, где это необходимо.

Сравнение разных вариантов решения с нативной реализацией

Мы решили сравнить:

  • lodash.sortby

  • WikiSort javascript адаптация (WikiSort)

  • QuickSort нативная реализация V8 (node.js 10.22.0)

  • TimSort нативная реализация V8 (node.js 14.5.0)

В ходе теста было создано 10 массивов со случайным сортируемым значением, в каждом из которых было по 100 тысяч объектов.

Из этого графика можно сделать вывод: после оптимизаций, которые провел движок V8, сортировка WikiSort не уступает нативной реализации TimSort, хотя при первых сортировках разница довольно заметная. А вот lodash я бы не стал советовать.

Посмотреть результаты теста подробнее можно тут sort-test-js, а исходный код тут Tihon-Ustinov/sort-test-js

Где стабильно?

версия

дата релиза

движок JavaScript

стабильность

Node.js

11.0.0

2018-10-23

V8 7.0.276.28

+

Node.js

10.22.0

2020-07-21

V8 6.8.275.32

-

Google Chrome

70.0.3538

2018-10-16

V8 7.0.276

+

Google Chrome

69.0.3497

2018-09-04

V8 6.9.427

-

Выводы

  • Не верьте в магию JavaScript, у всех странных кейсов в этом языке есть объяснение

  • Изучайте технологии, которые вы используете

  • Читайте официальную документацию

  • Следите за тем, что появляется в новых версиях

  • Не думайте, что уже все сделано и придумано, и вам нужно только использовать готовые решения

Источник: habr.com
К списку статей
Опубликовано: 29.09.2020 12:13:11
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании ростелеком

Javascript

Алгоритмы

Программирование

Сортировка

Разработка

Алгоритмы сортировки

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru