diff --git a/src/test/java/puzzle/PerformanceTest.java b/src/test/java/puzzle/PerformanceTest.java new file mode 100644 index 0000000..765be6c --- /dev/null +++ b/src/test/java/puzzle/PerformanceTest.java @@ -0,0 +1,66 @@ +package puzzle; + +import lombok.val; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import puzzle.SwedishGenerator.Rng; +import puzzle.SwedishGenerator.Slotinfo; + +import java.util.Locale; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static puzzle.SwedishGenerator.fillMask; + +public class PerformanceTest { + + @Test + @Disabled + void testPerformance() { + val rng = new Rng(42); + val dict = DictData.DICT; + + // 1. Stress test Clue Generation (Mask Generation) + System.out.println("[DEBUG_LOG] --- Mask Generation Performance ---"); + int[] clueSizes = {20, 25, 30}; + for (int size : clueSizes) { + long t0 = System.currentTimeMillis(); + val masker = new Masker(rng, new int[SwedishGenerator.STACK_SIZE], Masker.Clues.createEmpty()); + // Increased population and generations for stress + val mask = masker.generateMask(size, 200, 100, 50); + long t1 = System.currentTimeMillis(); + double duration = (t1 - t0) / 1000.0; + System.out.printf(Locale.ROOT, "[DEBUG_LOG] Size %d (pop=200, gen=100): %.3fs%n", size, duration); + // Basic sanity check: should not take forever + assertTrue(duration < 10.0, "Mask generation took too long for size " + size); + } + + // 2. Stress test Word Filler + System.out.println("[DEBUG_LOG] \n--- Word Filler Performance ---"); + for (int size : clueSizes) { + val masker = new Masker(rng, new int[SwedishGenerator.STACK_SIZE], Masker.Clues.createEmpty()); + val mask = masker.generateMask(size, 100, 50, 20); + + val slots = Masker.extractSlots(mask, dict.index()); + val slotInfo = Masker.scoreSlots(slots); + val grid = mask.toGrid(); + + long t0 = System.currentTimeMillis(); + // Try to fill multiple times to get a better average + int iterations = 3; + long totalNodes = 0; + long totalBacktracks = 0; + int successCount = 0; + for (int i = 0; i < iterations; i++) { + val result = fillMask(rng, slotInfo, grid.copy(), false); + if (result.ok()) successCount++; + totalNodes += result.nodes(); + totalBacktracks += result.backtracks(); + } + long t1 = System.currentTimeMillis(); + double totalDuration = (t1 - t0) / 1000.0; + + System.out.printf(Locale.ROOT, "[DEBUG_LOG] Size %d: %d/%d SUCCESS | avg nodes=%d | avg backtracks=%d | total time=%.3fs%n", + size, successCount, iterations, totalNodes / iterations, totalBacktracks / iterations, totalDuration); + } + } +}