/**
 * Simulasi tiga jebakan benchmark JVM — warmup, dead code elimination,
 * dan pengukuran sekali jalan — memakai penghitung satuan kerja dan
 * pembukuan hasil, bukan pengukuran waktu sungguhan.
 */
public class PerangkapBenchmark {

    static long lubangHitam = 0; // pengganti Blackhole JMH: penampung hasil
    static int hasilTerpakai = 0;

    static int kerja(int i) {
        return (i * 31 + 7) % 1000;
    }

    public static void main(String[] args) {
        // ---- Jebakan 1: warmup (model biaya bertingkat JIT) ----
        System.out.println("== Jebakan 1: warmup (satuan kerja per eksekusi) ==");
        long[] eksekusiKe = {1, 100, 10_000, 1_000_000};
        String[] mode = {"interpreter  ", "interpreter  ", "compiled (C1) ", "compiled (C2) "};
        int[] biaya = {3, 3, 1, 1};
        System.out.printf("%10s %15s %6s%n", "eksekusi ke", "mode", "biaya");
        for (int i = 0; i < eksekusiKe.length; i++) {
            System.out.printf("%10d %15s %6d%n", eksekusiKe[i], mode[i], biaya[i]);
        }
        System.out.println("ukur 100 eksekusi pertama -> 3 satuan/eksekusi");
        System.out.println("ukur setelah steady state -> 1 satuan/eksekusi");
        System.out.println("selisih 3x tanpa satu baris kode berubah");
        System.out.println();

        // ---- Jebakan 2: dead code elimination ----
        System.out.println("== Jebakan 2: dead code elimination ==");
        int n = 2000;

        // Harness naif: hasil dihitung lalu dibuang
        for (int i = 0; i < n; i++) {
            int hasilDibuang = kerja(i); // tidak pernah dibaca lagi
            if (hasilDibuang == Integer.MIN_VALUE) {
                System.out.println("tidak akan pernah tercetak");
            }
        }
        System.out.println("harness naif  : " + n + " eksekusi, hasil terpakai = "
            + hasilTerpakai + " -> pekerjaan rentan dihapus JIT");

        // Harness benar: hasil dialirkan ke lubang hitam
        for (int i = 0; i < n; i++) {
            lubangHitam += kerja(i);
            hasilTerpakai++;
        }
        System.out.println("harness benar : " + n + " eksekusi, hasil terpakai = "
            + hasilTerpakai + " (checksum " + lubangHitam + ")");
        System.out.println();

        // ---- Jebakan 3: satu pengukuran vs berulang ----
        System.out.println("== Jebakan 3: satu angka vs beberapa angka ==");
        int[] sampel = {7, 7, 8, 7, 9}; // "pengukuran" tetap, mis. satuan kerja
        int satuAngka = sampel[sampel.length - 1];
        int min = Integer.MAX_VALUE;
        int maks = Integer.MIN_VALUE;
        long total = 0;
        for (int s : sampel) {
            min = Math.min(min, s);
            maks = Math.max(maks, s);
            total += s;
        }
        double rerata = (double) total / sampel.length;
        double deviasi = 100.0 * (satuAngka - rerata) / rerata;
        System.out.println("satu pengukuran : " + satuAngka);
        System.out.printf("5 pengukuran    : min %d, rerata %.1f, maks %d%n", min, rerata, maks);
        System.out.printf("kesimpulan satu angka menyimpang %.1f%% dari rerata%n", deviasi);
    }
}
