Я встретил баг, который я сразу не предвидел, что называется "подводный камень"
И решил о нем рассказать, дело даже не в задаче, оригинальная задача требует именно наибольшего перформанса.
Моя ошибка была в том, что я предположил, что если я создаю объект с ключами строками равными true, то только эти строки будучи используемы как ключи дадут ожидаемый результат.
Так как я разрабатываю библиотеку валидации, я стараюсь сделать её как можно более широкой в использовании. И как можно более производительной.
Если Set поддерживается браузером — то это хорошо, и его вполне можно и нужно использовать. Скорость проверки O(1)
Но если не так, то Set заменяется полифилом. Производительность которого может быть гораздо ниже. (Я видел полифил, где это происходит за O(n), что мне точно не подходит)
Другой вопрос — что для валидации строк — мне не обязательно нужен Set — и я вполне могу обойтись решением №3. Которое гарантированно быстро и корректно работает.
Вы абсолютно правы! Именно это я и делаю. Опишу контекст последовательно:
Backend может возвращать неверные данные
Значит нужно валидировать эти даные
Для валидации нужно использовать библиотеку для валидации данных
В библиотеке валидации данных решается задача валидации набора строк.
Вы правы, в каждом конкретном случае это решение может быть медленее(если массив достаточно мал)
Я не краду у оптимизатора возможность оптимизировать. Я меняю ту операцию, которую он должен оптимизировать с "проверка на наличие элемента в неизменном массиве" на "взятие по ключу в неизменном объекте"
Думаю, что includes может быть оптимизирован до O(log N) или даже O(1), если он учтёт, что массив не меняется. Но предполагаю, что моё решение с изначальным O(log N) будет оптимизировано ещё больше.
Использование Javascript — одна из предпосылок статьи, так как он является дефакто стандартом веб разработки.
Но дело не в его динамичности, а в способах гарантии валидности данных приходящих по сети. Какой бы язык я не выбрал для своей разработки, он не даст мне гарантий корректности чужой программы(Бекенда).
Решение этой задачи необходимо внутри кода библиотеки валидации.
Мне нравится как вы сразу атакуете даже не зная контекста задачи. Проблема возникла внутри библиотеки для валидации данных с API. Где typescript просто не властен ничего сделать)
У меня есть подозрения что вы немного преждевременно делаете выводы.
Гляньте на эти замеры. У меня вообще вышло что Решение №3 самое быстрое.
Статья скорее про баг, чем про решение задачи.
Я встретил баг, который я сразу не предвидел, что называется "подводный камень"
И решил о нем рассказать, дело даже не в задаче, оригинальная задача требует именно наибольшего перформанса.
Моя ошибка была в том, что я предположил, что если я создаю объект с ключами строками равными true, то только эти строки будучи используемы как ключи дадут ожидаемый результат.
Что оказалось не правдой.
Поэтому я статью и написал
Интересный пример, а попробуйте замерить тот ключ который отсутствует
Это не сложно) когда это строгая типизация была сложной?
Другой вопрос что на фронте редко когда проект написан на подобном языке
Докажите что это не быстрее на примере)
Это код из подобной библиотеки, задача как раз внутри такой библиотеки и возникает, в других проектах — это не нужно
Решение #3 валидирует тип как и должно — гарантирует что это строка из массива
Так как я разрабатываю библиотеку валидации, я стараюсь сделать её как можно более широкой в использовании. И как можно более производительной.
Если Set поддерживается браузером — то это хорошо, и его вполне можно и нужно использовать. Скорость проверки O(1)
Но если не так, то Set заменяется полифилом. Производительность которого может быть гораздо ниже. (Я видел полифил, где это происходит за O(n), что мне точно не подходит)
Другой вопрос — что для валидации строк — мне не обязательно нужен Set — и я вполне могу обойтись решением №3. Которое гарантированно быстро и корректно работает.
Вы абсолютно правы! Именно это я и делаю. Опишу контекст последовательно:
Backend может возвращать неверные данные
Значит нужно валидировать эти даные
Для валидации нужно использовать библиотеку для валидации данных
В библиотеке валидации данных решается задача валидации набора строк.
Эту задачу я тут и описал.
Вы правы.
Дело как раз в том, что эта функция и есть та которая предназначалась для того, чтобы проверить тип. Такой как:
Typescript не кинет ошибку, если бекенд пришлёт невалидные данные.
Вы правы, в каждом конкретном случае это решение может быть медленее(если массив достаточно мал)
Я не краду у оптимизатора возможность оптимизировать. Я меняю ту операцию, которую он должен оптимизировать с "проверка на наличие элемента в неизменном массиве" на "взятие по ключу в неизменном объекте"
Думаю, что includes может быть оптимизирован до O(log N) или даже O(1), если он учтёт, что массив не меняется. Но предполагаю, что моё решение с изначальным O(log N) будет оптимизировано ещё больше.
Это не код проекта, это код библиотеки валидации(то что вы назвали функцией assertValid)
Абсолютно согласен. Но когда нет контроля за API третьих лиц — только так и можно.
Использование Javascript — одна из предпосылок статьи, так как он является дефакто стандартом веб разработки.
Но дело не в его динамичности, а в способах гарантии валидности данных приходящих по сети. Какой бы язык я не выбрал для своей разработки, он не даст мне гарантий корректности чужой программы(Бекенда).
Решение этой задачи необходимо внутри кода библиотеки валидации.
Typescript не может гарантировать, что бекенд пришлёт необходимый тип.
Я ответил на ваш вопрос, в разделе FAQ
Вы правильно уловили суть того, где этот код применяется. На самом деле это проблема возникла в моей библиотеке валидации данных
Мне нравится как вы сразу атакуете даже не зная контекста задачи. Проблема возникла внутри библиотеки для валидации данных с API. Где typescript просто не властен ничего сделать)