У css-modules есть досадный минус: из коробки они плохо типизированы. Если написать import styles from './Comp.module.css'; , то styles оказывается просто Record<string, string>. Есть какие-то дополнительные нашлепки, которые генерят *.d.ts, но это так себе.
На текущем проекте используем vanilla-extract, вполне устраивает.
ТСО не добавляют в js, потому что смысла в этом нет. Если функция подходит для ТСО, то её проще и правильнее переписать на цикл. Тот же "хвостовой" факториал выглядит искусственно в сравнении с обычным: "технический" второй параметр, запутанная логика.
Странно конечно, что canvas всё равно выигрывает. Возможно потому, что там не "честные" глифы рисуют.
canvas вообще не рисует, у него есть метод, который просто измеряет размеры строки в пикселях, но там нельзя например задать ограничение по ширине, то есть никакого выравнивания он не делает. Потому и быстрый.
История про то, как внутри браузера реализована некая довольно полезная функциональность, но по каким-то причинам до сих пор нет нормального браузерного api к ней, и пришлось дублировать реализацию. Не в первый раз, кажется.
Ну не совсем всё, arr не попал в копилку. А вот дальше разбираться не стали. Но возможно (хотя и нельзя сказать наверняка), что оптимизирующий компилятор v8 более аккуратно отследит все ссылки и таки выкинет data на мороз, тут не знаю.
Хотя конкретно в этом примере компилятор может не знать дальнейшую судьбу функции, переданной в arr.find, но эффект воспроизводится даже в таком случае, где всё очевидно:
Уже где-то писал, что в бинарном поиске (который "обычный") среднее количество итераций будет почти как как максимальное, log(n). То есть lowerBound и upperBound требуют в среднем в два раза меньше сравнений, поэтому обычный поиск лучше сделать через один из них, а не писать отдельно.
В замыкание попала data. Это потому, что все упоминаемые во внутренних функциях объекты садятся в одну "лодку", на которую все эти внутренние функции будут ссылаться. И неважно, что (item) => item === data в мусорке, общий объект продолжает жить - на него ссылается func
А, понял. Да, согласен, решение рабочее. Можно ли его обобщить на N групп (по которым распределяются числа k, 2k, ..., N*k)?
Мой вариант для 6 групп: определяем в числе степени множителей 2, 3 и 5, пусть это будут a, b, c. Тогда число попадает в группу (a + 3b + 5c) % 6. Для N групп надо рассматривать степени всех простых множителей меньше N, но не совсем понятно, как подобрать коэффициенты для суммы..
Вопрос: при каком максимальном d существует решение при такой постановке?
Любопытный апгрейд. Разбивку 2n чисел можно сделать, если d равен наибольшему нечетному простому числу, которое меньше чем n. Тогда каждому четному можно подобрать пару в виде нечетного. Причем если вышло так, что d = n-1, то больше точно нельзя (тривиально доказывается). Но вот всегда ли это максимум, не совсем понятно...
Разбиение ряда на группы - прикольная тема. Я вот что вспомнил: как разбить весь натуральный ряд (все целые больше 0) на 6 групп, так чтобы для любого k, числа k, 2k, 3k, 4k, 5k и 6k попадали в разные группы. Там тоже простое изящное решение в духе статьи.
Интересный пример one-person компании - Photopea, веб-аналог фотошопа. Чел за несколько лет без всякого ИИ запилил весь код в одно лицо, неплохо поднимает на рекламе и платных подписках
currentColor широко используется в svg, он точно не забыт. Хотя вот я сейчас узнал, что можно не только в svg )
Дней медведевских прекрасное начало
То ли Гайдара, то ли Чубайса
У css-modules есть досадный минус: из коробки они плохо типизированы. Если написать
import styles from './Comp.module.css';, тоstylesоказывается просто Record<string, string>. Есть какие-то дополнительные нашлепки, которые генерят *.d.ts, но это так себе.На текущем проекте используем vanilla-extract, вполне устраивает.
ТСО не добавляют в js, потому что смысла в этом нет. Если функция подходит для ТСО, то её проще и правильнее переписать на цикл. Тот же "хвостовой" факториал выглядит искусственно в сравнении с обычным: "технический" второй параметр, запутанная логика.
Человек не может объективно оценивать период, в который он был молод, ностальгия неизменно измажет всё яркими красками.
canvas вообще не рисует, у него есть метод, который просто измеряет размеры строки в пикселях, но там нельзя например задать ограничение по ширине, то есть никакого выравнивания он не делает. Потому и быстрый.
А если держать на странице отдельный iframe с минимумом верстки, и измерять текст внутри него - это тоже будет долгий layout рефлоу?
История про то, как внутри браузера реализована некая довольно полезная функциональность, но по каким-то причинам до сих пор нет нормального браузерного api к ней, и пришлось дублировать реализацию. Не в первый раз, кажется.
По разному бывает. На моей прошлой работе, например, схему (в дополнение к ТЗ) составляли аналитики, натурально записывая файлы вручную.
Так я об этом и написал )
Ну не совсем всё,
arrне попал в копилку. А вот дальше разбираться не стали. Но возможно (хотя и нельзя сказать наверняка), что оптимизирующий компилятор v8 более аккуратно отследит все ссылки и таки выкинетdataна мороз, тут не знаю.Хотя конкретно в этом примере компилятор может не знать дальнейшую судьбу функции, переданной в
arr.find,но эффект воспроизводится даже в таком случае, где всё очевидно:Но схемы умеют делать дополнительные проверки, например по регексу.
А вообще, имхо, источником правды должен быть сваггер/openApi, из которого на фронте генерятся типы и (при необходимости) валидаторы.
Уже где-то писал, что в бинарном поиске (который "обычный") среднее количество итераций будет почти как как максимальное, log(n). То есть lowerBound и upperBound требуют в среднем в два раза меньше сравнений, поэтому обычный поиск лучше сделать через один из них, а не писать отдельно.
В v8 (и наверно не только) всё ещё интереснее:
В замыкание попала
data. Это потому, что все упоминаемые во внутренних функциях объекты садятся в одну "лодку", на которую все эти внутренние функции будут ссылаться. И неважно, что(item) => item === dataв мусорке, общий объект продолжает жить - на него ссылаетсяfuncА, понял. Да, согласен, решение рабочее. Можно ли его обобщить на N групп (по которым распределяются числа k, 2k, ..., N*k)?
Мой вариант для 6 групп: определяем в числе степени множителей 2, 3 и 5, пусть это будут a, b, c. Тогда число попадает в группу
(a + 3b + 5c) % 6.Для N групп надо рассматривать степени всех простых множителей меньше N, но не совсем понятно, как подобрать коэффициенты для суммы..Да, этот момент всё портит) Пока не уверен, что здесь можно пофиксить.
Моё решение немного другое
Любопытный апгрейд. Разбивку 2n чисел можно сделать, если d равен наибольшему нечетному простому числу, которое меньше чем n. Тогда каждому четному можно подобрать пару в виде нечетного. Причем если вышло так, что d = n-1, то больше точно нельзя (тривиально доказывается). Но вот всегда ли это максимум, не совсем понятно...
Разбиение ряда на группы - прикольная тема. Я вот что вспомнил: как разбить весь натуральный ряд (все целые больше 0) на 6 групп, так чтобы для любого k, числа k, 2k, 3k, 4k, 5k и 6k попадали в разные группы. Там тоже простое изящное решение в духе статьи.
Интересный пример one-person компании - Photopea, веб-аналог фотошопа. Чел за несколько лет без всякого ИИ запилил весь код в одно лицо, неплохо поднимает на рекламе и платных подписках