Перейти к содержимому
RU
Играть

Форум

Niced

Пользователи
  • Публикации

    3 827
  • Зарегистрирован

  • Посещение

Все публикации пользователя Niced

  1. А, нет, все нормально. Если метода нет, то Котлин сам генерирует рандомный хэш для каждого объекта. Найти это не так просто в обфусцированном коде.
  2. Да, это так. Я снова залез в код и не нашел метода hashCode по крайней мере у одного типа объектов, которые хранятся в пуле. Это значит, что хэш у них 0 и все они находятся в одном большом списке с парами ключ/значение. *facepalm*
  3. Тут странных моментов вагон и маленькая тележка, но сам понимаешь, я постарался объяснить суть, чтобы многим было понятно, и тут без искажений смысла сложно обойтись. Идея, насколько я понимаю, в том, чтобы исключить попадание дублей одного объекта в пул, если он случайно возвращается несколько раз. Ошибкой было использование HashSet из стандартной библиотеки Котлина, который вычисляет хэш из состояния объекта (вызовом метода hashCode), и соответственно разные объекты могут иметь один хэш, что тоже забавный факт. Стоило использовать джаваскриптовский Set. HashSet - это HashMap внутри, функция first создает итератор по сету (чтобы просто получить первый элемент), внутри создается итератор по мапе, а мапа реализована как JS-объект, где имя свойства - хэш, а значение - элемент/элементы. Когда создается итератор по мапе, вызывается Object.keys() для получения массива всех хэшей. А вот из-за того, как работает Object.keys(), случается песец по производительности, когда пул становится достаточно большой. Стандартная библиотека Котлина.
  4. @The_3uFuPKa Привет. Возможно, на аккаунт входит кто-то другой. Попробуй сменить пароль или настроить двухфакторную аутентификацию. Если не поможет - скорее всего, проблема с соединением. Будем копать в эту сторону.
  5. Niced

    Технические работы

    На самом деле нет: Надеемся, что с этим что-нибудь сделают.
  6. Niced

    Флуда требуют наши сердца!

    Гискард не сможет опознать шафторака, что очень опасно для нахождения оного на форуме! Или если ты вдруг "мальчик, играющий на девчачьей пушке Изиде" - никто об этом не узнает и твоя репутация останется в безопасности. На скриншоты или видео из битвы можно отвечать, что это монтаж и компиляция.
  7. Niced

    Флуда требуют наши сердца!

    Сильно сказано. Может, ты способен предсказывать судьбу по профилю?
  8. Niced

    Не могу зайти в игру

    Неактивность автора. Закрыто.
  9. Niced

    Флуда требуют наши сердца!

    Смотрите в настройках игры, на вкладке "Безопасность". Можно убрать свой профиль из рейтингов. Изменения вступают в силу в течение 20 минут.
  10. Niced

    Флуда требуют наши сердца!

    @Fizzika В курсе новой настройки конфиденциальности профиля на Рейтингах?
  11. Я тут загуглил, возможно даже O(n log n) сложность: https://stackoverflow.com/a/64912755 Что интересно: Named properties on most objects that occur in practice (up to about a thousand properties) are (usually) stored in creation order in a special kind of internal array, so they can be retrieved in O(n) and don't need to be sorted. Скорее всего, этим и объясняется существенное падение производительности после достижения пулом размера около тысячи объектов.
  12. Давно не виделись! Время офигительных историй. Какое-то время назад я заметил одну вещь, которая, скажем так, меня расстраивала (на самом деле у меня дико горело). Симптомы проблемы такие: происходит лаг на несколько секунд (из-за интернета или задержки на сервере), но мы люди привычные, и все бы ничего, если бы после лага производительность не падала до конца битвы, порой превращая игру в лютый лагодром. В прямом смысле: начинаются просадки FPS, картинка дергается и играть становится некомфортно. Помогает только перезагрузка. И вот, в один из таких случаев, я вооружился профайлером и записал происходящее: Да, так иногда начинает работать игра после разового лага, это тяжелый случай. Сверху - время между кадрами, которое, как мы видим, сильно отличается от комфортных 16.6 мс. Чрезвычайно много времени занимает как подготовка кадров, так и обработка данных из сети. Вот как выглядит обработка одного сетевого события: С сервера приходят данные, затем цепочка вызовов приводит к функции createDust, которая, как можно понять из названия, отвечает за эффект пыли. В конце все упирается в некую функцию с обфусцированным именем mi, и ее выполнение занимает большую часть времени не только в этом событии, но и вообще во всей записи длительностью 24 секунды: 13 секунд суммарно занимает выполнение одной лишь функции. Что же она делает? Последняя функция в цепочке, назначение которой можно легко вывести из названия - createDustParticle, и вот ее код: Нас интересуют два вызова метода get в начале (мы видели их на втором скриншоте), которые приводят к злосчастной функции mi. Срезая углы скажу, что это извлечение объекта из пула, где хранятся экземпляры часто используемых игрой объектов - таких как эффекты выстрелов, пыли, гильз и т. п. Принцип работы с пулом: взял объект, поработал с ним, вернул обратно в пул. Таким образом можно ограничиться уже созданными экземплярами, что снижает нагрузку на сборщик мусора (ведь новых объектов не создается и их не надо удалять, когда они становятся не нужны), ну и сэкономить на их создании, если оно дорого. Клиент ТО активно задействует пулы. Взглянем на код метода get и метода, возвращающего объект в пул: По-русски: "если пул пустой, создаем новый объект и возвращаем его; если там что-то есть - достаем первый объект, удаляем его из пула и возвращаем". На самом деле не первый, а любой объект. Потому что тип хранилища - HashSet, и оно не сохраняет порядок элементов, у него нет начала и конца. Чтобы получить первый или последний - не важно - элемент из сета, функция first_7wnvza$ (а точнее та самая функция mi, вызываемая далее) создает список всех элементов в коллекции, и берет нужный из этого списка. Снова: чтобы получить ОДИН элемент из коллекции, библиотечная (т. е. ее написали не наши разработчики) функция каждый раз заносит ВСЕ ее содержимое (точнее, хэши всех элементов, но это детали) в список. Насколько это медленно? Зависит от размера коллекции. В большинстве обычных сценариев это норм, но НЕ В КОДЕ, КОТОРЫЙ ВЫЗЫВАЕТСЯ 100500 РАЗ. Камон, у вас сложность O(n) там, где легко можно было обойтись O(1), используя для хранения объектов не hash set, а массив/список. Да, не совсем понятно как быть в случае, если объект по ошибке возвращается несколько раз, но можно дополнительно держать hash set для проверки - и это все равно было бы быстрее. И да, вспоминая цель существования пулов: чтобы достать один объект, реализация "за кулисами" создает минимум два в процессе. Гениально. Можно предположить, что разработчики слепо понадеялись на реализацию, предоставляемую стандартной библиотекой. Во-первых, в таком критичном к производительности коде, как пулы, это по умолчанию плохой подход. Во-вторых, неужели клиент не отлаживается в реальных боевых условиях, в самом замесе? Даже при легкой игре какие-то непонятные функции отнимают многовато времени для реалтайм-приложения: Никого это не смущает? Ладно, а что же с адским лагодромом? Обратим взоры на метод, возвращающий объект обратно в пул. Можно легко заметить, что создание объектов в методе get никак не ограничено (если пул пуст), как и в методе put_11rb$ не ограничено их возращение. Пул у нас безразмерный: надо игре 100500 объектов - она запрашивает их из пула, пул их при необходимости создает, после использования они возвращаются обратно и размер пула увеличивается. Дело в том, что трудно угадать подходящий размер пула заранее. Объекты могут закончиться, а без них игра не работает. Тем не менее, неограниченное помещение объектов обратно в пул - потенциальная утечка памяти, что вкупе с крайне неоптимальной реализацией самого пула и приводит к описанной проблеме. Итак, происходит вот что, как я предполагаю. В "жаркий" момент битвы, когда клиенту необходимо быстро обрабатывать/отрисовывать множество выстрелов, эффектов овердрайвов, пыли из-под гусениц и прочего, с сервера сыплется куча данных. Если в этот момент случается ощутимый лаг (что в нашей игре не редкость), необработанные данные накапливаются. Когда же наконец производится их обработка, из-за большого количества одновременно происходящих событий на карте (и связанных с ними эффектов) объектов в пуле не хватает и он серьезно увеличивается в размерах. По мере его роста игре заметно плохеет, вплоть до неиграбельности. Я пробовал имитировать лаги и проверять количество объектов в пулах, и точно могу сказать, что объяснение выше имеет смысл. Когда счет объектов в пулах идет на тысячи, начинаются заметные просадки. Т. е. чтобы играть стало резко некомфортно, нужен серьезный замес и достаточно продолжительный лаг, однако в любом случае игра постепенно замедляется во время битвы. Также я пробовал заменить hash set на массив - игра прекрасно работает (порой несколько миллисекунд выигрыша за фрейм). Более того, я пробовал отключать пулы совсем - игра прекрасно работает, и сборщик мусора вроде не проявляет себя сильнее обычного. Еще я отключал пыль и гильзы в настройках (советую сделать, пока эту фигню не пофиксили), что сильно снижает нагрузку на пулы, но это же не наш метод! Вот, надеюсь, кому-нибудь было интересно это небольшое расследование. Хочу добавить, что это все можно было описать куда компактнее, потому что то, о чем я говорю - далеко не rocket science, это базовые вещи. Цель была показать, что сторонний пользователь, вооружившись доступными инструментами способен находить слонов в комнате, по какой-то причине игнорируемых разработчиками.
  13. Еще у разработчиков и ютуберов есть.
  14. А кто это? Фидбэк будет соответствовать стилю игры - барской охоте в рандоме на самом-самом. Эти люди иначе не играют, так что они по определению biased. Может и трио.
  15. Меня там не было? Тоже только что видел первых двух в этом же составе. Конфа наверное.
  16. Вообще это нормально. Насколько я знаю, на широкую публику механизм работы ММ не озвучивался, что делает патчноут вызывающим вопросы. Для многих игроков получился рассказ про сепульки и сепуление.
  17. В смысле через неделю у всех? "Ранний доступ" в ультра-контейнерах неизвестно сколько продлится.
×
×
  • Создать...