perf: cut per-tick allocation and collapse STARS into one scheduler task
Цель — не средний тик, а разброс: p95 26.9 мс и пики под 170 мс на 60 ботах бьют по игрокам сильнее, чем медиана 14.8 мс. Почти весь этот разброс шёл от мусора в горячих путях. 1. Кеш владельца ножа переехал в начало проверки. Раньше isOwner() сначала звал BlackKnifeItem.is() на обеих руках и только потом смотрел ownerCache, то есть кеш не срабатывал никогда. is() обязан взять ItemMeta, а Bukkit возвращает там полную копию метаданных вместе с PDC. tickShield() зовёт isOwner каждый тик на каждого игрока: при 60 игроках это 2400 копий ItemMeta в секунду. Теперь на попадание в кеш — ноль аллокаций, пересчёт раз в 2 с. Кеш хранит оба ответа сразу (в руках / где-то в инвентаре), потому что hasMagic и превью интересуют разные вещи. 2. BlackKnifeItem.inHands() вместо пары is() в горячих путях: 7 проверок превью прицеливания и SWOON на каждый удар. 3. DustOptions вынесены в константы Particles. 36 мест создавали new Particle.DustOptions(Color.fromRGB(...)), и почти все внутри циклов или задач с периодом в несколько тиков. DustOptions иммутабелен, поэтому один объект на цвет. Отдельно вынесен тернарник, выбиравший цвет кольца ВНУТРИ цикла в превью SNIPE/TRI: он пересчитывал один и тот же цвет на каждой из 12-16 итераций. 4. getGazePoint() больше не зовёт getEyeLocation() три раза и getDirection() два. Метод работает каждые 4 тика на каждого игрока с ножом. 5. Визуал STARS вынесен в StarFx под одну задачу. Раньше 18 звёзд и до 108 осколков получали по своей задаче с периодом в один тик — до 126 задач планировщика на одно нажатие, каждая со своим getNearbyEntities и getNearbyPlayers. Теперь один список под одной задачей, которая снимает себя сама в простое. Попутно исправлен баг: EntityTracker.untrack() вызывался на каждом тике, пока сущность жива, поэтому после первого тика она исчезала из множества отслеживаемых и EntityTracker.cleanup() её больше не находил. Теперь untrack вызывается один раз, при удалении.
This commit is contained in:
@@ -162,13 +162,13 @@ public class GrenadeAttack {
|
||||
double a = (double) k / 16 * Math.PI * 2;
|
||||
Location ring = g.clone().add(Math.cos(a) * LETHAL_RADIUS, 0, Math.sin(a) * LETHAL_RADIUS);
|
||||
p.spawnParticle(Particle.DUST, ring, 1, 0, 0, 0, 0,
|
||||
new Particle.DustOptions(Color.fromRGB(255, 40, 40), 1.2f));
|
||||
Particles.RED_12);
|
||||
}
|
||||
for (int k = 0; k < 24; k++) {
|
||||
double a = (double) k / 24 * Math.PI * 2;
|
||||
Location ring = g.clone().add(Math.cos(a) * CHIP_RADIUS, 0, Math.sin(a) * CHIP_RADIUS);
|
||||
p.spawnParticle(Particle.DUST, ring, 1, 0, 0, 0, 0,
|
||||
new Particle.DustOptions(Color.fromRGB(255, 200, 60), 1.0f));
|
||||
Particles.GOLD_10);
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(plugin, 1L, 1L);
|
||||
@@ -191,7 +191,7 @@ public class GrenadeAttack {
|
||||
expl.getWorld().spawnParticle(Particle.EXPLOSION, expl, 2);
|
||||
expl.getWorld().spawnParticle(Particle.SMOKE, expl, 12, 0.3, 0.3, 0.3, 0.05);
|
||||
expl.getWorld().spawnParticle(Particle.DUST, expl, 10, 0.3, 0.2, 0.3, 0,
|
||||
new Particle.DustOptions(Color.fromRGB(255, 120, 30), 1.2f));
|
||||
Particles.ORANGE_12);
|
||||
expl.getWorld().playSound(expl, Sound.ENTITY_GENERIC_EXPLODE, 1f, 1.1f);
|
||||
TensionManager tm = plugin.getTension();
|
||||
for (LivingEntity le : expl.getWorld().getNearbyLivingEntities(expl, CHIP_RADIUS + 0.5)) {
|
||||
|
||||
Reference in New Issue
Block a user