1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Итерация по всей коллекции или загрузка определенных данных если игрок рядом с ними?

Тема в разделе "Разработка плагинов для новичков", создана пользователем MurlikMurlik, 5 ноя 2018.

  1. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Доброго времени суток.
    Начала тревожить мысль производительности, если я делаю итерацию по огромной коллекции, скажем HashSet.
    Например я пишу плагин на свои кровати. Каждый раз когда игрок просыпается с кровати, записывается в бд и в HashSet координаты, имя игрока. (если уже на ней спал то не записывается)
    Когда кто либо ломает блок кровати, я тупо делаю итерацию по всей коллекции и ищу совпадения координат, что бы удалить кровать ну и например оповестить владельца. Что произойдет, если скажем, на сервере будет более 100к таких кроватей с разными игроками? (я возможно преувеличил) При разрушении кровати, будет большая задержка, и даже в некоторых случаев просто так, ибо совпадения может и не быть.
    Дак вот ближе к сути. Каким образом можно оптимизировать это дело? Слышал что можно каким то образом подгружать поблизости от игрока объекты, правда я не понимаю каким образом, ибо наличие уже такого количества объектов при подгрузке возле игрока, тоже сильно скажется на производительности возможно..
    Каким то образом WorldGuard же с огромным количеством приватов спокойно держит на плаву сервер.
     
  2. EnderBro3D

    EnderBro3D Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    EnderBro3D
    Ну ты же не подгружаешь всё кровати при запуске сервера, я надеюсь))
    загружай кровати, когда заходит игрок, не будет дофига записей (если конечно онлайн не 500+)
     
  3. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    К сожалению, в этом и есть вся основная проблема, что я все загружаю в память. Можно взять аналогию с приватами. Владельца привата нет.. но он чудом есть. Тут тоже самое, мне жизненно важно так сказать, держать их всех в памяти, что бы при разрушении другим игроком, был всегда результат.
     
  4. _Nanit_

    _Nanit_ Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    _Nanit_
    Используй TreeMap. Скорость поиска в больших списках в разы быстрее чем в листе или том же hashset, потому что данные в нем автоматически сортируются. Ну и итерировать самому ничего не надо, просто containsKey(Location).
     
  5. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Ну.. я делаю итерацию что бы получить ссылку на объект. А объект у меня не простой, хранит локацию, баккит игрока, ник. И при сравнении, мне нужно получить объект свой, что бы там уже достать нужные данные этого игрока, у меня там не просто проверка локации)
     
  6. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Ещё предложу вариант.
    Раздели данные на те, которые формируют ключ, и на остальные.
    Например, ключ может включать название мира и x, y, z. Перенеси их в свой маленький pojo, переопредели equals и hashcode (например, lombok-ом). Используй объект такого типа как K в Map<K, V>.
    Поиск (когда кто-то ломает кровать) будет O(1).
     
  7. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Последнее редактирование: 6 ноя 2018
  8. Exception_Prototype

    Exception_Prototype Активный участник Пользователь

    Баллы:
    96
    Никогда все приваты не висели в памяти, они загружаются по требованию и если какое то время не юзаются - выгружаются. В WG для этого своя система, но есть готовый вариант в гугл либе: https://pastebin.com/2WSe7HN1
    Не забудь прочитать документацию, потом что там нужно знать некоторые делали + посмотреть примеры.
     
  9. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Честно говоря, большая часть терминов мне не знакома) Но в остальном, третий раз перечитав, я понял), разве что я без понятия что значит "будет O(1)"? Я слышал про это в некоторых коллекциях, но не могу понять что это значит.
    В принципе, я когда выбирал между мапой и сетом, меня больше заинтересовало то, что за одну итерацию я сразу же получу целый объект. По карте более ресурсоемко по моему. Ну вот так я по крайней мере делал:
    Код:
    private Set<ObjectTest> test = new HashSet<ObjectTest>();
    
    public void testRun(String name) {
    ObjectTest ot = null;
    for (ObjectTest o : test) {
    if (o.getName().equals(name)) {
    ot = 0;
    break;
    }
    //а тут я уже делаю что нибудь например
    if (ot != null) {
    //что то
    }
    
    }
    }

    Код:
    private Map<String, ObjectTest> test = new HashMap<String, ObjectTest>();
    
    public void testRun(String name) {
    for (String s : test.keySet()) {
    if (s.equals(name)) {
    ObjectTest ot = test.get(s); //я же получается, делаю итерацию по ключам и потом второй раз итерацию но уже методом карты, что бы вернуть значение.. вроде бы медленнее чем делать тупо по одному сету.
    if (ot != null) {
    //что то делаю
    }
    }
    }
    Поэтому я почти везде использую хешсет. Без понятия, прав ли я, поэтому отписался)
     
  10. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    А подгружаемые чанки, должны хранится в какой то коллекции? Я просто еще молод так сказать, вообще без понятия, как реализовать то что вы предлагаете, ну по крайней мере как я понял.
    Просто насколько я понял, будет объект в котором информация о координатах самого чанка. А так же, список всех локаций.. и как я понял, при разрушении блока, будет подружатся этот чанк условно говоря, и уже проверка всех кроватей этого объекта? А как я получу этот чанк, если их будет много? Тоже итерацией? Просто вообще не понимаю.
     
  11. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Хотел бы узнать принцип работы или хотя бы пример подобной системы)
     
  12. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    А стопе, туплю. Я зря делаю итерацию по всем ключам? Мне достаточно просто попробовать достать значение, а там уже в зависимости от данных (например если нулл вернул, значит там пусто и не нашел), я сразу же получу результат?
     
  13. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Тут уже все готово же. Тебе только 3 метода юзать add и contains, и время от времени Save для очистки озу. Допишешь сам, если надо записывать больше одного игрока на локацию.
     
    Последнее редактирование: 6 ноя 2018
  14. hyndorik

    hyndorik Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    hyndo
    Хрень ты написал собственно, то что ты скинул, что там, что там везде O(N) (линейное время). Хеш сет использует внутри хеш мапу, открыл бы чтоли посмотрел сорцы
     
  15. Автор темы
    MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Хотел бы узнать, почему используется битовый сдвиг здесь:
    int ChunkX = loc.getBlockX() >> 4;
    int ChunkZ = loc.getBlockZ() >> 4;
    Насколько я понял, это ты получаешь таким образом координаты чанка. Но ведь существует метод loc.getChunk().getX() || loc.getChunk().getZ()
    Или без разницы вообще?
     
  16. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Ну если там тоже самое, то без разницы.
     
  17. hyndorik

    hyndorik Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    hyndo
    Так в методе с чанком они же используются, да и посчитаны координаты заранее, так что смысла тут их еще раз выводить из обычных координат нет
     

Поделиться этой страницей