diff --git a/engine/build.gradle b/engine/build.gradle index 1a3d6ec0..8502452a 100644 --- a/engine/build.gradle +++ b/engine/build.gradle @@ -76,7 +76,6 @@ dependencies { // Spring api 'org.springframework.boot:spring-boot-starter' - api 'org.springframework.boot:spring-boot-starter-aop' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/DefaultTimeProfilerService.java b/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/DefaultTimeProfilerService.java new file mode 100644 index 00000000..020437e4 --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/DefaultTimeProfilerService.java @@ -0,0 +1,42 @@ +package com.bartlomiejpluta.base.core.profiling.time; + +import com.bartlomiejpluta.base.core.gc.Cleanable; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +@Slf4j +@Component +public class DefaultTimeProfilerService implements TimeProfilerService, Cleanable { + private static final DecimalFormat DF = new DecimalFormat("0.00"); + private final Map averages = new HashMap<>(); + + @Override + public void measure(String key, Runnable task) { + var start = System.nanoTime(); + task.run(); + var time = System.nanoTime() - start; + + if (!averages.containsKey(key)) { + averages.put(key, time * 1.0); + } else { + averages.put(key, (averages.get(key) + time) / 2.0); + } + } + + @Override + public void cleanUp() { + averages.entrySet().stream() + .sorted(Entry.comparingByValue().reversed()) + .forEachOrdered(entry -> log.info("[{}]: [{}ms] [{}us] [{}ns]", + entry.getKey(), + DF.format(entry.getValue() / 1_000_000), + DF.format(entry.getValue() / 1_000), + DF.format(entry.getValue()) + )); + } +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/TimeProfilerService.java b/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/TimeProfilerService.java new file mode 100644 index 00000000..839addeb --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/TimeProfilerService.java @@ -0,0 +1,5 @@ +package com.bartlomiejpluta.base.core.profiling.time; + +public interface TimeProfilerService { + void measure(String key, Runnable task); +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/annotation/MeasureExecutionTime.java b/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/annotation/MeasureExecutionTime.java deleted file mode 100644 index 8e6597d1..00000000 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/annotation/MeasureExecutionTime.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.bartlomiejpluta.base.core.profiling.time.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface MeasureExecutionTime { -} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/aspect/ExecutionTimeAspect.java b/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/aspect/ExecutionTimeAspect.java deleted file mode 100644 index c3c164ca..00000000 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/profiling/time/aspect/ExecutionTimeAspect.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.bartlomiejpluta.base.core.profiling.time.aspect; - -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.stereotype.Component; - -@Slf4j -@Aspect -@Component -@ConditionalOnExpression("${app.profiling.aspects:false}") -public class ExecutionTimeAspect { - - @Around("@annotation(com.bartlomiejpluta.base.core.stat.metrics.annotation.MeasureExecutionTime)") - public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { - long start = 0; - long end = 0; - long elapsed; - Object result; - try { - start = System.nanoTime(); - result = joinPoint.proceed(); - } finally { - end = System.nanoTime(); - } - - elapsed = end - start; - log.debug("[{}.{}] = [{}s] [{}ms] [{}ns]", - joinPoint.getTarget().getClass().getSimpleName(), - joinPoint.getSignature().getName(), - elapsed / 1000000.0, elapsed / 1000.0, elapsed - ); - - return result; - } -} diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java b/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java index d5ddc0dc..f6ed12df 100644 --- a/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java +++ b/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java @@ -6,6 +6,7 @@ import com.bartlomiejpluta.base.core.gl.render.Renderer; import com.bartlomiejpluta.base.core.image.ImageManager; import com.bartlomiejpluta.base.core.logic.GameLogic; import com.bartlomiejpluta.base.core.profiling.fps.FPSMonitor; +import com.bartlomiejpluta.base.core.profiling.time.TimeProfilerService; import com.bartlomiejpluta.base.core.ui.Window; import com.bartlomiejpluta.base.core.util.mesh.MeshManager; import com.bartlomiejpluta.base.core.world.map.GameMap; @@ -26,6 +27,7 @@ public class DefaultGameLogic implements GameLogic { private final TextureManager textureManager; private final EntityManager entityManager; private final ImageManager imageManager; + private final TimeProfilerService profiler; private final FPSMonitor fpsMonitor; private GameMap map; diff --git a/game/src/main/resources/application.yml b/game/src/main/resources/application.yml index 6feb2cbe..05f40b87 100644 --- a/game/src/main/resources/application.yml +++ b/game/src/main/resources/application.yml @@ -7,9 +7,6 @@ app: core: targetUps: 50 # Updates per second - profiling: - aspects: false - sprite: entity: dimension: