package unit; import java.util.*; /** * ElementWebTest — CWE-407 benchmark for element-web-0001 * * element-web-0001: apps/web/src/TextForEvent.tsx:503 * textForPowerEvent() deduplicates user IDs from power level event using indexOf on an array. * Two forEach loops each calling indexOf (O(n)) to build a dedup list — total O(N²). * * Slow: for each userId in contentUsers ∪ prevContentUsers: indexOf on accumulator array * Fast: Set union in O(N) * * compile: javac -d . ElementWebTest.java && java -ea unit.ElementWebTest */ public class ElementWebTest { static void bench(String label, Runnable slow, Runnable fast, long sOps, long fOps) { slow.run(); fast.run(); // warmup long t0 = System.nanoTime(); slow.run(); long sMs = (System.nanoTime() - t0) / 1_000_000; long t1 = System.nanoTime(); fast.run(); long fMs = (System.nanoTime() - t1) / 1_000_000; double ratio = fOps > 0 ? (double) sOps / fOps : 0; System.out.printf(" %-60s slow:%4dms (%,d ops) fast:%4dms (%,d ops) speedup:%.0fx%n", label, sMs, sOps, fMs, fOps, ratio); } // ----------------------------------------------------------------------- // element-web-0001: users.indexOf dedup in forEach loop // ----------------------------------------------------------------------- /** * Slow: Array.indexOf inside forEach — O((A+B)²) * Simulates building a dedup list from two sets of user IDs. * Returns total comparison operations performed. */ static long slowPowerEventDedup(int contentUsers, int prevContentUsers) { List contentKeys = new ArrayList<>(); for (int i = 0; i < contentUsers; i++) contentKeys.add("user-" + i); // prevContent has some overlap + some new users List prevKeys = new ArrayList<>(); for (int i = contentUsers / 2; i < contentUsers / 2 + prevContentUsers; i++) prevKeys.add("user-" + i); List users = new ArrayList<>(); long ops = 0; // forEach(userId => if (users.indexOf(userId) === -1) users.push(userId)) for (String userId : contentKeys) { ops += users.size(); // cost of indexOf scan (grows as list fills) if (!users.contains(userId)) users.add(userId); } for (String userId : prevKeys) { ops += users.size(); // cost of indexOf scan if (!users.contains(userId)) users.add(userId); } return ops; } /** * Fast: Set union — O(A + B) * Returns total operations (one per element). */ static long fastPowerEventDedup(int contentUsers, int prevContentUsers) { List contentKeys = new ArrayList<>(); for (int i = 0; i < contentUsers; i++) contentKeys.add("user-" + i); List prevKeys = new ArrayList<>(); for (int i = contentUsers / 2; i < contentUsers / 2 + prevContentUsers; i++) prevKeys.add("user-" + i); long ops = 0; Set userSet = new LinkedHashSet<>(); for (String u : contentKeys) { userSet.add(u); ops++; } for (String u : prevKeys) { userSet.add(u); ops++; } // Array.from(userSet) — O(N) List users = new ArrayList<>(userSet); ops += users.size(); return ops; } public static void main(String[] args) { System.out.println("ElementWebTest — CWE-407 benchmarks"); System.out.println(); int passed = 0; int total = 0; // Small room (N=200 each side) { int A = 200, B = 200; long[] sOps = {0}, fOps = {0}; Runnable s = () -> sOps[0] = slowPowerEventDedup(A, B); Runnable f = () -> fOps[0] = fastPowerEventDedup(A, B); sOps[0] = slowPowerEventDedup(A, B); fOps[0] = fastPowerEventDedup(A, B); bench("element-web-0001 power event dedup indexOf vs Set (A=" + A + " B=" + B + ")", s, f, sOps[0], fOps[0]); total++; if (sOps[0] > fOps[0] * 10L) { System.out.println(" element-web-0001 small PASS (slow=" + sOps[0] + " > 10x fast=" + fOps[0] + ")"); passed++; } else { System.out.println(" element-web-0001 small FAIL (slow=" + sOps[0] + " fast=" + fOps[0] + ")"); } assert sOps[0] > fOps[0] * 10L : "element-web-0001 small: slow ops not 10x fast ops"; } // Large room (N=1000 each side — large server with many power level entries) { int A = 1000, B = 1000; long[] sOps = {0}, fOps = {0}; Runnable s = () -> sOps[0] = slowPowerEventDedup(A, B); Runnable f = () -> fOps[0] = fastPowerEventDedup(A, B); sOps[0] = slowPowerEventDedup(A, B); fOps[0] = fastPowerEventDedup(A, B); bench("element-web-0001 power event dedup indexOf vs Set (A=" + A + " B=" + B + ")", s, f, sOps[0], fOps[0]); total++; if (sOps[0] > fOps[0] * 50L) { System.out.println(" element-web-0001 large PASS (slow=" + sOps[0] + " > 50x fast=" + fOps[0] + ")"); passed++; } else { System.out.println(" element-web-0001 large FAIL (slow=" + sOps[0] + " fast=" + fOps[0] + ")"); } assert sOps[0] > fOps[0] * 50L : "element-web-0001 large: slow ops not 50x fast ops"; } System.out.println(); System.out.println(passed + "/" + total + " PASS"); } }