Pull to refresh

Comments 14

Да, тоже его видел, там действительно на setTimeout и это скорее на данный момент единственное похожее решение (по крайней мере я других не вижу пока что). Когда нибудь и они поддержат этот метод:)

Посмотрите, пожалуйста, какая метрика будет, если использовать setTimeout:

isOpenedCollapse ? getFilterData() : setTimeout(getFilterData(), 0);

В данном случае пришлось поставить задержку процессора в производительности, так как на мощных компах (которые есть не у всех пользователей) разницы практически нет.

Какой итог?

При применении setTimeout(getFilterData,0) расчет начинается после прохождения цикла в EventLoop и возникает такая ситуация:
- Просчитались открытые категории
- Сайдбар открылся
- Нажать никуда не получается, так как начал отрабатывать колбек из таймаута и начались расчеты закрытых категорий, а пользователь в это время теряет интерактивность, так как еще не все успело подгрузиться и отрисоваться

При применении requestIdleCallback такой проблемы с потерей интерактивности интерфейса замечено не было (пробовал несколько раз)

У вас, блин, какие-то КЛИЕНТСКИЕ расчеты занимают секунду и вас это не беспокоит, но беспокоит когда и что рисовать?? Вот она - проблема доморощенных программистов без базовых знаний.

Какой у вас там алгоритм для «расчетов»? O(n^10)?

Проблема не в сложности алгоритмов, а в количестве прилетаемых данных. Сложность O(n^2), так как идет маппинг по категориям (их максимум 5) и дальше внутри категорий раскидываются данные по компонентам фильтров в зависимости от вида фильтра. При этом данные уже преобразованные, поэтому дополнительных преобразований не производится, кроме как просто распределения данных по компонентам.

И как я и писал проблема возникает только при большой выдаче, так как фильтров может прилететь очень много.

Можно сказать, что это бред, но как я и сказал - это внутренний продукт и достаточно специфичный и из-за такой специфики возникают такие сложности, поэтому прошу не переходить на оскорбления

Данных не может быть СТОЛЬКО. У меня на миллионах строк на клиенте алгоритмы отрабатывают быстрее секунды, а тут фильтры… O(n^2) - это значит что вы не заморачивались с алгоритмом, я на 100% уверен, что там можно сделать как минимум O(n*log2n) и процентов на 50, что можно и O(n).

Там просто незачем проходить что-то в двух циклах, при этом не используя ни деревья ни хэш-таблицы…

Я могу вам показать тоже внутренний проект, где тоже много фильтров и они тоже пересекаются и даже пользователь сам может создавать свои фильтры на псевдо-SQL языке и они применяются к набору данных в 70 миллионов строк меньше чем за секунду :)

Ничего не тормозит нигде, без всяких шаманств с браузером.

Я за 28 лет опыта уже такого повидал выше крыши, даже похожие алгоритмы с «маппингом» исправлял. Такие проблемы - как минимум повод пересмотреть архитектуру проекта.

P.S.: Про доморощенного программиста - это не оскорбление, а предположение. Или у вас есть профильное математическое образованием знание базы в виде как минимум программы матфака, устройства ПК и опыта разработки на ассемблере и C/C++ и я не прав? Опять же, по характеру «проблемы» и выбранному способу её «решения» я предположил то, что написал.

Да, техническое образование у меня есть, в котором присутствовал и ассемблер и C++. И я бы с удовольствием взглянул на ваш алгоритм, возможно действительно можно улучшить, так как я вполне осознаю, что это на данный момент временное решение и по хорошему улучшить алгоритм отрисовки

Способ решения выбран был просто - необходимо сделать быстрее в короткий срок без долгих обдумываний и переделок. Плюс это новый метод, который хотелось опробовать и который неплохо справляется в данной ситуации

Алгоритмов там на 2407 строк C++ кода (расширение для PHP) + 3570 строк кода сам PHP скрипт, функционал - динамическое сравнение групп AB-тестов.

До перевода кода на C++ в расширение этот же функционал рендерил страницу около минуты и потреблял больше 2 ГБ памяти. Сейчас - меньше секунды.

Как можно поменять ваш алгоритм - самое простое - вместо внутреннего цикла берите данные из map-а, а сам внутренний цикл вынесите наружу и поменяйте код на заполнение этого map-а. Получится O(n * log2n), если map будет hash_map, то получится O(n). Осталось придумать что в хэше будет ключом.

Отрисовка должна быть однопроходной в принципе. Все алгоритмы должны быть не в отрисовке, а в формировании данных так, чтобы отрисовка была однопроходной.

Спасибо, возьму на заметку. Как будет время покопаюсь)

Спасибо за статью, очень информативное изложение!

Sign up to leave a comment.

Articles