' Loop Optimization — precompute invariants, hoist calculations
#COMPILE EXE
#DIM ALL

SUB NaiveMultiplication()
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL result AS LONG
    LOCAL count AS LONG
    count = 0
    PRINT "=== NAIVE (no optimization) ==="
    FOR i = 1 TO 10
        FOR j = 1 TO 10
            result = i * j
            count = count + 1
        NEXT j
    NEXT i
    PRINT "Count = " & STR$(count) & ", result = " & STR$(result)
    PRINT
END SUB

SUB InvariantHoisting()
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL result AS LONG
    LOCAL count AS LONG
    LOCAL columnSum AS LONG
    count = 0
    PRINT "=== INVARIANT HOISTING ==="
    PRINT "Naive inner loop computes column sum each iteration"
    PRINT "Optimized: precompute column sums before inner loop"
    FOR j = 1 TO 3
        columnSum = 0
        FOR i = 1 TO 10
            columnSum = columnSum + i
            count = count + 1
        NEXT i
        PRINT "Column " & STR$(j) & " sum = " & STR$(columnSum)
    NEXT j
    PRINT "Inner loop iterations: " & STR$(count)
    PRINT
END SUB

SUB StrengthReduction()
    LOCAL i AS LONG
    LOCAL square AS LONG
    LOCAL naiveCount AS LONG
    LOCAL optCount AS LONG
    PRINT "=== STRENGTH REDUCTION ==="
    PRINT "Computing squares of 1 to 20"
    PRINT "Naive: i * i each time"
    PRINT "Optimized: use (i-1)^2 + 2i - 1"
    square = 0
    FOR i = 1 TO 20
        square = square + 2 * i - 1
        PRINT "Square " & STR$(i) & " = " & STR$(square) & " (verify: " & STR$(i * i) & ")"
    NEXT i
    PRINT
END SUB

SUB LoopUnrolling()
    LOCAL i AS LONG
    LOCAL sum AS LONG
    LOCAL t1 AS LONG
    LOCAL t2 AS LONG
    PRINT "=== LOOP UNROLLING ==="
    PRINT "Sum 1 to 10000"
    t1 = TIMER
    sum = 0
    FOR i = 1 TO 10000
        sum = sum + i
    NEXT i
    t2 = TIMER
    PRINT "Normal loop: " & STR$(sum) & " (" & STR$(t2 - t1) & " ms)"
    t1 = TIMER
    sum = 0
    FOR i = 1 TO 10000 STEP 10
        sum = sum + i
        sum = sum + (i + 1)
        sum = sum + (i + 2)
        sum = sum + (i + 3)
        sum = sum + (i + 4)
        sum = sum + (i + 5)
        sum = sum + (i + 6)
        sum = sum + (i + 7)
        sum = sum + (i + 8)
        sum = sum + (i + 9)
    NEXT i
    t2 = TIMER
    PRINT "Unrolled loop: " & STR$(sum) & " (" & STR$(t2 - t1) & " ms)"
    PRINT
END SUB

SUB BoundsCheckHoisting()
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL n AS LONG
    LOCAL sum AS LONG
    n = 100
    PRINT "=== BOUNDS CHECK HOISTING ==="
    PRINT "Compute sum of 1/(i+j-1) for i,j in 1..n"
    PRINT "Hoist: compute LEN/UBOUND once instead of each iteration"
    sum = 0
    FOR i = 1 TO n
        FOR j = 1 TO n
            sum = sum + (i + j - 1)
        NEXT j
    NEXT i
    PRINT "Sum = " & STR$(sum)
    PRINT
END SUB

SUB CachedComputation()
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL sinCache(1 TO 10) AS DOUBLE
    LOCAL sum AS DOUBLE
    PRINT "=== CACHED COMPUTATION ==="
    PRINT "Precomputing SIN values outside inner loop:"
    FOR i = 1 TO 10
        sinCache(i) = SIN(i * 0.1)
    NEXT i
    sum = 0
    FOR i = 1 TO 10
        FOR j = 1 TO 10
            sum = sum + sinCache(i) * sinCache(j)
        NEXT j
    NEXT i
    PRINT "Cached sum = " & FORMAT$(sum, "###.####")
    PRINT
END SUB

FUNCTION PBMAIN() AS LONG
    PRINT "============================"
    PRINT " Loop Optimization Demo"
    PRINT "============================"
    PRINT
    CALL NaiveMultiplication()
    CALL InvariantHoisting()
    CALL StrengthReduction()
    CALL LoopUnrolling()
    CALL BoundsCheckHoisting()
    CALL CachedComputation()
    PRINT "Loop optimization demos complete."
    FUNCTION = 0
END FUNCTION
