tomcat-0001: WebSocket getNegotiatedSubprotocol List.contains O(R×S) MEDIUM 52x hibernate-orm-0001: FK ordering buildRecursiveOrderedFkSecondPasses List.contains O(N²) HIGH 2.8x netty-0001: ALPN select/selected List.contains O(S×P) MEDIUM 26x netty-0002: DnsResolveContext dedup ArrayList.contains O(R²) MEDIUM 30x All 4/4 unit tests PASS.
90 lines
3.6 KiB
Java
90 lines
3.6 KiB
Java
import java.util.*;
|
|
|
|
/**
|
|
* Unit test for netty-0002: DnsResolveContext
|
|
* ArrayList.contains() dedup O(R²) → companion HashSet O(R).
|
|
*/
|
|
public class Netty0002Test {
|
|
|
|
// --- BEFORE: O(R²) ArrayList dedup ---
|
|
static List<String> resolveBefore(List<String> records, boolean duplicateAllowed) {
|
|
List<String> finalResult = null;
|
|
for (String record : records) {
|
|
if (finalResult == null) {
|
|
finalResult = new ArrayList<>(8);
|
|
finalResult.add(record);
|
|
} else if (duplicateAllowed || !finalResult.contains(record)) { // O(R)
|
|
finalResult.add(record);
|
|
}
|
|
}
|
|
return finalResult != null ? finalResult : Collections.emptyList();
|
|
}
|
|
|
|
// --- AFTER: O(R) companion HashSet dedup ---
|
|
static List<String> resolveAfter(List<String> records, boolean duplicateAllowed) {
|
|
List<String> finalResult = null;
|
|
Set<String> finalResultSet = null;
|
|
for (String record : records) {
|
|
if (finalResult == null) {
|
|
finalResult = new ArrayList<>(8);
|
|
finalResultSet = new HashSet<>(8);
|
|
finalResult.add(record);
|
|
finalResultSet.add(record);
|
|
} else if (duplicateAllowed || !finalResultSet.contains(record)) { // O(1)
|
|
finalResult.add(record);
|
|
finalResultSet.add(record);
|
|
}
|
|
}
|
|
return finalResult != null ? finalResult : Collections.emptyList();
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
// Correctness with duplicates
|
|
List<String> records = Arrays.asList("1.2.3.4", "5.6.7.8", "1.2.3.4", "9.10.11.12", "5.6.7.8");
|
|
|
|
List<String> beforeResult = resolveBefore(records, false);
|
|
List<String> afterResult = resolveAfter(records, false);
|
|
assert beforeResult.equals(afterResult) : "Dedup results must match: " + beforeResult + " vs " + afterResult;
|
|
assert beforeResult.size() == 3 : "Expected 3 unique, got " + beforeResult.size();
|
|
System.out.println("PASS correctness dedup: " + beforeResult);
|
|
|
|
// Correctness with duplicates allowed
|
|
List<String> beforeDup = resolveBefore(records, true);
|
|
List<String> afterDup = resolveAfter(records, true);
|
|
assert beforeDup.equals(afterDup) : "Dup-allowed results must match";
|
|
assert beforeDup.size() == 5 : "Expected 5 with dups, got " + beforeDup.size();
|
|
System.out.println("PASS correctness dup-allowed: " + beforeDup);
|
|
|
|
// Performance: R=1000 records, 50% duplicates
|
|
int R = 1000;
|
|
List<String> bigRecords = new ArrayList<>();
|
|
for (int i = 0; i < R; i++) {
|
|
bigRecords.add("10.0." + (i % (R / 2)) / 256 + "." + (i % (R / 2)) % 256);
|
|
}
|
|
|
|
// Warmup
|
|
for (int w = 0; w < 500; w++) {
|
|
resolveBefore(bigRecords, false);
|
|
resolveAfter(bigRecords, false);
|
|
}
|
|
|
|
int iterations = 3000;
|
|
long t0 = System.nanoTime();
|
|
for (int i = 0; i < iterations; i++) {
|
|
resolveBefore(bigRecords, false);
|
|
}
|
|
long beforeNs = System.nanoTime() - t0;
|
|
|
|
t0 = System.nanoTime();
|
|
for (int i = 0; i < iterations; i++) {
|
|
resolveAfter(bigRecords, false);
|
|
}
|
|
long afterNs = System.nanoTime() - t0;
|
|
|
|
double ratio = (double) beforeNs / afterNs;
|
|
System.out.printf("PASS performance: before=%dms after=%dms ratio=%.1fx (R=%d)%n",
|
|
beforeNs / 1_000_000, afterNs / 1_000_000, ratio, R);
|
|
assert ratio > 2.0 : "Expected at least 2x speedup, got " + ratio;
|
|
System.out.println("PASS all tests for netty-0002");
|
|
}
|
|
}
|