Помогите Радиус относительно location.

pro100koder

Активный участник
Пользователь
Баллы
76
Обшарил немножко интернет, особо ничего не нашёл, кроме getNearblyEntities(), но с этим как-то не разобрался... Что мне нужно: из ArrayList-a доставать локацию, и в радиусе от этой локации искать игроков (К примеру, локация на координатах 1 33 7, если в радиусе 2 блоков от этой локации есть игрок/игроки, отправлять им сообщение, на пример.)
 
Обшарил немножко интернет, особо ничего не нашёл, кроме getNearblyEntities(), но с этим как-то не разобрался... Что мне нужно: из ArrayList-a доставать локацию, и в радиусе от этой локации искать игроков (К примеру, локация на координатах 1 33 7, если в радиусе 2 блоков от этой локации есть игрок/игроки, отправлять им сообщение, на пример.)
Так используй getNearbyEntities и проверяй если entity - игрок.
 
Код:
java.util.List<Entity> getNearbyEntities(double x, double y, double z)
Returns a list of entities within a bounding box centered around this entity
Ты получаешь всех существ (включая игроков) в заданном кубоиде от текущей локации. К примеру если будет кубоид 5, 2, 5, то это значит что по X в две стороны 5 блоков, по Z в две стороны по 5 блоков, по Y в две стороны по 2 блока. Кубоид размером 10 на 4 на 10. Далее смотри по своей ситуации. Перебираешь всех этих существ в кубоиде, затем отсеиваешь только игроков, затем отсеиваешь среди них по дистанции уже реальной (если нужно тебе конкретно в радиусе).
Простой пример:
PHP:
int r = 10;
Set<Entity> entities = world.getNearbyEntitites(location, r, r, r);
Set<Player> players = new HashSet<>(); // Это будет конечный результат
for (Entity entity : entities) {
    if (!(entity instanceof Player)) continue;
    if (location.distance(entity.getLocation()) > r) continue;
    players.add((Player) entity));
}
Можно реализовать проще на Java 8:
PHP:
int r = 10;
Set<Player> players = world.getNearbyEntities(location, r, r, r).stream()
    .filter(entity -> entity instanceof Player)
    .filter(entity -> entity.getLocation().distance(location) <= r)
    .map(entity -> (Player) entity).collect(Collectors.toSet());
 
Последнее редактирование:
Код:
java.util.List<Entity> getNearbyEntities(double x, double y, double z)
Returns a list of entities within a bounding box centered around this entity
Ты получаешь всех существ (включая игроков) в заданном кубоиде от текущей локации. К примеру если будет кубоид 5, 2, 5, то это значит что по X в две стороны 5 блоков, по Z в две стороны по 5 блоков, по Y в две стороны по 2 блока. Кубоид размером 10 на 4 на 10. Далее смотри по своей ситуации. Перебираешь всех этих существ в кубоиде, затем отсеиваешь только игроков, затем отсеиваешь среди них по дистанции уже реальной (если нужно тебе конкретно в радиусе).
PHP:
int r = 10;
Set<Entity> entities = world.getNearbyEntitites(location, r, r, r);
Set<Player> players = new HashSet<>(); // Это будет конечный результат
for (Entity entity : entities) {
    if (!(entity instanceof Player)) continue;
    if (location.distance(entity.getLocation()) > r) continue;
    players.add((Player) entity));
}
Проблема в том, что "центр" кубоида - локация, а не существо. Вот немножечко моего г.кода:
Код:
public static ArrayList<Location> sl = new ArrayList<Location>();

for(int i=0;i<sl.size();i++){
            Location loc = sl.get(i);
for (Entity entity : loc.getNearbyEntities(1, 1, 1)) {
                if (entity.getType() == EntityType.PLAYER) {
                    players.add(((Player) entity));
                }
            }
И там в строчке "for (Entity entity : loc.getNearbyEntities(1.0, 1.0, 1.0)) {" вылезает ошибка, добавить cast, что loc - entity, если так сделать, будет, что бы вы думали? Правильно, ошибки в консоли.
 
Проблема в том, что "центр" кубоида - локация, а не существо. Вот немножечко моего г.кода:
Код:
public static ArrayList<Location> sl = new ArrayList<Location>();

for(int i=0;i<sl.size();i++){
            Location loc = sl.get(i);
for (Entity entity : loc.getNearbyEntities(1, 1, 1)) {
                if (entity.getType() == EntityType.PLAYER) {
                    players.add(((Player) entity));
                }
            }
И там в строчке "for (Entity entity : loc.getNearbyEntities(1.0, 1.0, 1.0)) {" вылезает ошибка, добавить cast, что loc - entity, если так сделать, будет, что бы вы думали? Правильно, ошибки в консоли.
Есть два варианта:
- Брать от World -> World#getNearbyEntitites(location, rx, ry, rz)
- Брать от существа (Entity) -> Entity#getNearbyEntitites(rx, ry, rz)

Тебе как раз подходит 1 вариант: loc.getWorld().getNearbyEntitites(loc, ....)
 
Есть два варианта:
- Брать от World -> World#getNearbyEntitites(location, rx, ry, rz)
- Брать от существа (Entity) -> Entity#getNearbyEntitites(rx, ry, rz)

Тебе как раз подходит 1 вариант: loc.getWorld().getNearbyEntitites(loc, ....)
Есть еще вариант 3, итератор на всех игроков и .distance() (метод точно не помню) проверять
 
Есть еще вариант 3, итератор на всех игроков и .distance() (метод точно не помню) проверять
Да, точно, как то не вспомнил даже.
PHP:
Set<Player> players = world.getPlayers().stream()
        .filter(player -> player.getLocation().distance(location) <= r)
        .collect(Collectors.toSet());
 
Практически одинаково. Даже при огромных массивах данных.
На огромных массивах данных не считать квадратный корень не будет быстрее, чем считать квадратный корень?
 
Будет чутку быстрее, но почти одинаково.
На stackoverflow среди комментов кто-то говорил что на половину быстрее, нормального полного ответа не нашёл. Лично мне лень тестить, фиолетово как-то, просто знаю что оно быстрее и что в ядре используют в квадрате.
 
На stackoverflow среди комментов кто-то говорил что на половину быстрее, нормального полного ответа не нашёл. Лично мне лень тестить, фиолетово как-то, просто знаю что оно быстрее и что в ядре используют в квадрате.
Я пробовал бенчмарки делать, пробовал с рандомом, без, пробовал с полной формулой (включая квадраты и т.д.), пробовал без. Кол. операций на секунду было почти одинаковое. Может быть JIT подкачал, но что есть, то пишу.
 
Я пробовал бенчмарки делать, пробовал с рандомом, без, пробовал с полной формулой (включая квадраты и т.д.), пробовал без. Кол. операций на секунду было почти одинаковое. Может быть JIT подкачал, но что есть, то пишу.
Хотелось бы видеть эти бенчмарки )) прогрев делал? ))
 
Хотелось бы видеть эти бенчмарки )) прогрев делал? ))
Делал, вот сам код:
https://privatebin.net/?6e86ec35b102a83e#KXZqBo1Siv5qkjZX8BzfdLTAVhGKPjz70aWEV714jmM=
Вот результат:
Код:
Benchmark              Mode  Cnt      Score      Error   Units
MyBenchmark.fastSqrt  thrpt    5  78900,371 ±  421,628  ops/ms
MyBenchmark.sqrt      thrpt    5  73468,187 ± 1149,025  ops/ms

Если найдешь здесь ошибки по оптимизации результатов, буду признателен.
Код:
# JMH version: 1.21
# VM version: JDK 1.8.0_151, Java HotSpot(TM) 64-Bit Server VM, 25.151-b12
# VM invoker: C:\Program Files\Java\jre1.8.0_151\bin\java.exe
# VM options: -Dfile.encoding=UTF-8
# Warmup: 3 iterations, 3 s each
# Measurement: 5 iterations, 5 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: ua.i0xhex.benchmark.MyBenchmark.fastSqrt

# Run progress: 0,00% complete, ETA 00:01:08
# Fork: 1 of 1
# Warmup Iteration   1: 74715,939 ops/ms
# Warmup Iteration   2: 74238,698 ops/ms
# Warmup Iteration   3: 78574,523 ops/ms
Iteration   1: 78968,207 ops/ms
Iteration   2: 78765,202 ops/ms
Iteration   3: 79029,288 ops/ms
Iteration   4: 78812,270 ops/ms
Iteration   5: 78926,890 ops/ms


Result "ua.i0xhex.benchmark.MyBenchmark.fastSqrt":
  78900,371 ±(99.9%) 421,628 ops/ms [Average]
  (min, avg, max) = (78765,202, 78900,371, 79029,288), stdev = 109,496
  CI (99.9%): [78478,743, 79321,999] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_151, Java HotSpot(TM) 64-Bit Server VM, 25.151-b12
# VM invoker: C:\Program Files\Java\jre1.8.0_151\bin\java.exe
# VM options: -Dfile.encoding=UTF-8
# Warmup: 3 iterations, 3 s each
# Measurement: 5 iterations, 5 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: ua.i0xhex.benchmark.MyBenchmark.sqrt

# Run progress: 50,00% complete, ETA 00:00:34
# Fork: 1 of 1
# Warmup Iteration   1: 70689,527 ops/ms
# Warmup Iteration   2: 69663,753 ops/ms
# Warmup Iteration   3: 73249,735 ops/ms
Iteration   1: 73956,293 ops/ms
Iteration   2: 73533,717 ops/ms
Iteration   3: 73325,395 ops/ms
Iteration   4: 73329,234 ops/ms
Iteration   5: 73196,293 ops/ms


Result "ua.i0xhex.benchmark.MyBenchmark.sqrt":
  73468,187 ±(99.9%) 1149,025 ops/ms [Average]
  (min, avg, max) = (73196,293, 73468,187, 73956,293), stdev = 298,398
  CI (99.9%): [72319,162, 74617,212] (assumes normal distribution)


# Run complete. Total time: 00:01:09

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark              Mode  Cnt      Score      Error   Units
MyBenchmark.fastSqrt  thrpt    5  78900,371 ±  421,628  ops/ms
MyBenchmark.sqrt      thrpt    5  73468,187 ± 1149,025  ops/ms
 
Т.к. в проверяемом цикле практически нет ветвлений, кроме next(), я бы заменил его тело на:
Java:
index = (index + 1) % SIZE;
return randData[index];
Но в целом всё показательно, разница в 2.7 раза.
 
Т.к. в проверяемом цикле практически нет ветвлений, кроме next(), я бы заменил его тело на:
Java:
index = (index + 1) % SIZE;
return randData[index];
Но в целом всё показательно, разница в 2.7 раза.
Где ты там 2.7 нашел, по дельте или что?
Score 1 = 78900
Score 2 = 73468

Кстати после правки того выше, как то скорость немного упала:
return randData[index = (index + 1) % SIZE];
Код:
Benchmark              Mode  Cnt      Score      Error   Units
MyBenchmark.fastSqrt  thrpt    5  65464,644 ±  314,550  ops/ms
MyBenchmark.sqrt      thrpt    5  56119,564 ± 7057,873  ops/ms

В общем примерно +10% скорости, если без Math.sqrt.
 
Последнее редактирование:
Не использовать fpu когда есть такая возможность - крайне здравая мысль ибо бывают конфигураци где fpu может быть один на несколько ядер (привет пацанам из amd). Либо fpu может просто тормознутым чудовищем, или его вовсе может и не быть, и тогда конец, ибо тогда будет софтовый рассчёт, который адищенски медленный (arm-softfloat).
 
Где ты там 2.7 нашел, по дельте или что?
Я в шары долбился, error-ы поделил. Сорян.

P. S. Очень слегка модифицировал код, у меня получились такие результаты:
Код:
Benchmark              Mode  Cnt       Score      Error   Units
MyBenchmark.fastSqrt  thrpt    5  152268,596 ± 3755,570  ops/ms
MyBenchmark.sqrt      thrpt    5  128341,391 ± 5962,195  ops/ms
Я значительно уменьшил SIZE, чтобы минимизировать время доступа к памяти, т.к. мы измеряем не его; а также заинлайнил руками distanceSq в distance, чтобы глубина вызовов хотя бы в исходном коде была одинаковая.
Результат: 18.6% выигрыша.
 
Последнее редактирование:
Назад
Верх