import java.util.*; /** * Unit test for PCSX2 pcsx2-0002: GSCapture::GetCodecListForContainer * uses std::find_if on vector to deduplicate codec names during enumeration, * giving O(N^2) where N = number of codecs iterated. * * Fix: track seen codec names in an unordered_set for O(1) dedup. * * Defect file: pcsx2/GS/GSCapture.cpp line 1501 */ public class GSCaptureCodecDedupTest { // --- Defective: linear scan on list for dedup --- static List getCodecListDefective(List codecs) { List ret = new ArrayList<>(); for (String name : codecs) { boolean found = false; for (String existing : ret) { if (existing.equals(name)) { found = true; break; } } if (!found) { ret.add(name); } } return ret; } // --- Fixed: hash set dedup --- static List getCodecListFixed(List codecs) { List ret = new ArrayList<>(); Set seen = new HashSet<>(); for (String name : codecs) { if (seen.add(name)) { ret.add(name); } } return ret; } public static void main(String[] args) { int N = 500; // Build codec list with ~50% duplicates List codecs = new ArrayList<>(); for (int i = 0; i < N; i++) { codecs.add("codec_" + (i % (N / 2))); } // Correctness List resDef = getCodecListDefective(codecs); List resFix = getCodecListFixed(codecs); assert resDef.equals(resFix) : "Mismatch"; // Warmup for (int i = 0; i < 500; i++) { getCodecListDefective(codecs); getCodecListFixed(codecs); } int ITER = 5000; long t0 = System.nanoTime(); for (int i = 0; i < ITER; i++) getCodecListDefective(codecs); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); for (int i = 0; i < ITER; i++) getCodecListFixed(codecs); long fixNs = System.nanoTime() - t0; double ratio = (double) defNs / fixNs; System.out.printf("GSCapture codec dedup N=%d defect=%.1fms fixed=%.1fms ratio=%.1fx%n", N, defNs / 1e6, fixNs / 1e6, ratio); assert ratio > 2.0 : "Expected >2x speedup, got " + ratio; System.out.println("PASS"); } }