8236850: Operations on constant List/Set.of(element) instances does not consistently constant fold
Reviewed-by: smarks, jrose, rriggs, psandoz
This commit is contained in:
parent
631b4d2694
commit
de96aeddf5
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -78,9 +78,7 @@ static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = {
|
||||
// Entry fields for subgraphs archived in the open archive heap region.
|
||||
static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = {
|
||||
{"jdk/internal/module/ArchivedModuleGraph", "archivedModuleGraph"},
|
||||
{"java/util/ImmutableCollections$ListN", "EMPTY_LIST"},
|
||||
{"java/util/ImmutableCollections$MapN", "EMPTY_MAP"},
|
||||
{"java/util/ImmutableCollections$SetN", "EMPTY_SET"},
|
||||
{"java/util/ImmutableCollections", "archivedObjects"},
|
||||
{"java/lang/module/Configuration", "EMPTY_CONFIGURATION"},
|
||||
{"jdk/internal/math/FDBigInteger", "archivedCaches"},
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -56,9 +56,47 @@ class ImmutableCollections {
|
||||
* will vary between JVM runs.
|
||||
*/
|
||||
static final int SALT;
|
||||
|
||||
/**
|
||||
* For set and map iteration, we will iterate in "reverse" stochastically,
|
||||
* decided at bootstrap time.
|
||||
*/
|
||||
private static final boolean REVERSE;
|
||||
static {
|
||||
long nt = System.nanoTime();
|
||||
SALT = (int)((nt >>> 32) ^ nt);
|
||||
long color = 0x243F_6A88_85A3_08D3L; // pi slice
|
||||
long seed = System.nanoTime();
|
||||
SALT = (int)((color * seed) >> 16); // avoid LSB and MSB
|
||||
REVERSE = SALT >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constants following this might be initialized from the CDS archive via
|
||||
* this array.
|
||||
*/
|
||||
private static Object[] archivedObjects;
|
||||
|
||||
private static final Object EMPTY;
|
||||
|
||||
static final ListN<?> EMPTY_LIST;
|
||||
|
||||
static final SetN<?> EMPTY_SET;
|
||||
|
||||
static final MapN<?,?> EMPTY_MAP;
|
||||
|
||||
static {
|
||||
VM.initializeFromArchive(ImmutableCollections.class);
|
||||
if (archivedObjects == null) {
|
||||
EMPTY = new Object();
|
||||
EMPTY_LIST = new ListN<>();
|
||||
EMPTY_SET = new SetN<>();
|
||||
EMPTY_MAP = new MapN<>();
|
||||
archivedObjects = new Object[] { EMPTY, EMPTY_LIST, EMPTY_SET, EMPTY_MAP };
|
||||
} else {
|
||||
EMPTY = archivedObjects[0];
|
||||
EMPTY_LIST = (ListN)archivedObjects[1];
|
||||
EMPTY_SET = (SetN)archivedObjects[2];
|
||||
EMPTY_MAP = (MapN)archivedObjects[3];
|
||||
}
|
||||
}
|
||||
|
||||
/** No instances. */
|
||||
@ -386,11 +424,13 @@ class ImmutableCollections {
|
||||
private final E e0;
|
||||
|
||||
@Stable
|
||||
private final E e1;
|
||||
private final Object e1;
|
||||
|
||||
List12(E e0) {
|
||||
this.e0 = Objects.requireNonNull(e0);
|
||||
this.e1 = null;
|
||||
// Use EMPTY as a sentinel for an unused element: not using null
|
||||
// enable constant folding optimizations over single-element lists
|
||||
this.e1 = EMPTY;
|
||||
}
|
||||
|
||||
List12(E e0, E e1) {
|
||||
@ -400,7 +440,7 @@ class ImmutableCollections {
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return e1 != null ? 2 : 1;
|
||||
return e1 != EMPTY ? 2 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -409,11 +449,12 @@ class ImmutableCollections {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public E get(int index) {
|
||||
if (index == 0) {
|
||||
return e0;
|
||||
} else if (index == 1 && e1 != null) {
|
||||
return e1;
|
||||
} else if (index == 1 && e1 != EMPTY) {
|
||||
return (E)e1;
|
||||
}
|
||||
throw outOfBounds(index);
|
||||
}
|
||||
@ -425,7 +466,7 @@ class ImmutableCollections {
|
||||
|
||||
@java.io.Serial
|
||||
private Object writeReplace() {
|
||||
if (e1 == null) {
|
||||
if (e1 == EMPTY) {
|
||||
return new CollSer(CollSer.IMM_LIST, e0);
|
||||
} else {
|
||||
return new CollSer(CollSer.IMM_LIST, e0, e1);
|
||||
@ -434,7 +475,7 @@ class ImmutableCollections {
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
if (e1 == null) {
|
||||
if (e1 == EMPTY) {
|
||||
return new Object[] { e0 };
|
||||
} else {
|
||||
return new Object[] { e0, e1 };
|
||||
@ -444,7 +485,7 @@ class ImmutableCollections {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
int size = e1 == null ? 1 : 2;
|
||||
int size = size();
|
||||
T[] array = a.length >= size ? a :
|
||||
(T[])Array.newInstance(a.getClass().getComponentType(), size);
|
||||
array[0] = (T)e0;
|
||||
@ -461,16 +502,6 @@ class ImmutableCollections {
|
||||
static final class ListN<E> extends AbstractImmutableList<E>
|
||||
implements Serializable {
|
||||
|
||||
// EMPTY_LIST may be initialized from the CDS archive.
|
||||
static @Stable List<?> EMPTY_LIST;
|
||||
|
||||
static {
|
||||
VM.initializeFromArchive(ListN.class);
|
||||
if (EMPTY_LIST == null) {
|
||||
EMPTY_LIST = new ListN<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
private final E[] elements;
|
||||
|
||||
@ -564,13 +595,16 @@ class ImmutableCollections {
|
||||
implements Serializable {
|
||||
|
||||
@Stable
|
||||
final E e0;
|
||||
private final E e0;
|
||||
|
||||
@Stable
|
||||
final E e1;
|
||||
private final Object e1;
|
||||
|
||||
Set12(E e0) {
|
||||
this.e0 = Objects.requireNonNull(e0);
|
||||
this.e1 = null;
|
||||
// Use EMPTY as a sentinel for an unused element: not using null
|
||||
// enable constant folding optimizations over single-element sets
|
||||
this.e1 = EMPTY;
|
||||
}
|
||||
|
||||
Set12(E e0, E e1) {
|
||||
@ -584,7 +618,7 @@ class ImmutableCollections {
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return (e1 == null) ? 1 : 2;
|
||||
return (e1 == EMPTY) ? 1 : 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -594,12 +628,12 @@ class ImmutableCollections {
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
|
||||
return o.equals(e0) || e1.equals(o); // implicit nullcheck of o
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return e0.hashCode() + (e1 == null ? 0 : e1.hashCode());
|
||||
return e0.hashCode() + (e1 == EMPTY ? 0 : e1.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -613,13 +647,14 @@ class ImmutableCollections {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public E next() {
|
||||
if (idx == 1) {
|
||||
idx = 0;
|
||||
return SALT >= 0 || e1 == null ? e0 : e1;
|
||||
return (REVERSE || e1 == EMPTY) ? e0 : (E)e1;
|
||||
} else if (idx == 2) {
|
||||
idx = 1;
|
||||
return SALT >= 0 ? e1 : e0;
|
||||
return REVERSE ? (E)e1 : e0;
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
@ -634,7 +669,7 @@ class ImmutableCollections {
|
||||
|
||||
@java.io.Serial
|
||||
private Object writeReplace() {
|
||||
if (e1 == null) {
|
||||
if (e1 == EMPTY) {
|
||||
return new CollSer(CollSer.IMM_SET, e0);
|
||||
} else {
|
||||
return new CollSer(CollSer.IMM_SET, e0, e1);
|
||||
@ -643,9 +678,9 @@ class ImmutableCollections {
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
if (e1 == null) {
|
||||
if (e1 == EMPTY) {
|
||||
return new Object[] { e0 };
|
||||
} else if (SALT >= 0) {
|
||||
} else if (REVERSE) {
|
||||
return new Object[] { e1, e0 };
|
||||
} else {
|
||||
return new Object[] { e0, e1 };
|
||||
@ -655,12 +690,12 @@ class ImmutableCollections {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
int size = e1 == null ? 1 : 2;
|
||||
int size = size();
|
||||
T[] array = a.length >= size ? a :
|
||||
(T[])Array.newInstance(a.getClass().getComponentType(), size);
|
||||
if (size == 1) {
|
||||
array[0] = (T)e0;
|
||||
} else if (SALT >= 0) {
|
||||
} else if (REVERSE) {
|
||||
array[0] = (T)e1;
|
||||
array[1] = (T)e0;
|
||||
} else {
|
||||
@ -684,18 +719,9 @@ class ImmutableCollections {
|
||||
static final class SetN<E> extends AbstractImmutableSet<E>
|
||||
implements Serializable {
|
||||
|
||||
// EMPTY_SET may be initialized from the CDS archive.
|
||||
static @Stable Set<?> EMPTY_SET;
|
||||
|
||||
static {
|
||||
VM.initializeFromArchive(SetN.class);
|
||||
if (EMPTY_SET == null) {
|
||||
EMPTY_SET = new SetN<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
final E[] elements;
|
||||
|
||||
@Stable
|
||||
final int size;
|
||||
|
||||
@ -752,7 +778,7 @@ class ImmutableCollections {
|
||||
|
||||
private int nextIndex() {
|
||||
int idx = this.idx;
|
||||
if (SALT >= 0) {
|
||||
if (REVERSE) {
|
||||
if (++idx >= elements.length) {
|
||||
idx = 0;
|
||||
}
|
||||
@ -941,16 +967,6 @@ class ImmutableCollections {
|
||||
*/
|
||||
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
|
||||
|
||||
// EMPTY_MAP may be initialized from the CDS archive.
|
||||
static @Stable Map<?,?> EMPTY_MAP;
|
||||
|
||||
static {
|
||||
VM.initializeFromArchive(MapN.class);
|
||||
if (EMPTY_MAP == null) {
|
||||
EMPTY_MAP = new MapN<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
final Object[] table; // pairs of key, value
|
||||
|
||||
@ -1058,7 +1074,7 @@ class ImmutableCollections {
|
||||
|
||||
private int nextIndex() {
|
||||
int idx = this.idx;
|
||||
if (SALT >= 0) {
|
||||
if (REVERSE) {
|
||||
if ((idx += 2) >= table.length) {
|
||||
idx = 0;
|
||||
}
|
||||
@ -1284,7 +1300,7 @@ final class CollSer implements Serializable {
|
||||
return Set.of(array);
|
||||
case IMM_MAP:
|
||||
if (array.length == 0) {
|
||||
return ImmutableCollections.MapN.EMPTY_MAP;
|
||||
return ImmutableCollections.EMPTY_MAP;
|
||||
} else if (array.length == 2) {
|
||||
return new ImmutableCollections.Map1<>(array[0], array[1]);
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -789,7 +789,7 @@ public interface List<E> extends Collection<E> {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static <E> List<E> of() {
|
||||
return (List<E>) ImmutableCollections.ListN.EMPTY_LIST;
|
||||
return (List<E>) ImmutableCollections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1033,7 +1033,7 @@ public interface List<E> extends Collection<E> {
|
||||
switch (elements.length) { // implicit null check of elements
|
||||
case 0:
|
||||
@SuppressWarnings("unchecked")
|
||||
var list = (List<E>) ImmutableCollections.ListN.EMPTY_LIST;
|
||||
var list = (List<E>) ImmutableCollections.EMPTY_LIST;
|
||||
return list;
|
||||
case 1:
|
||||
return new ImmutableCollections.List12<>(elements[0]);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1288,7 +1288,7 @@ public interface Map<K, V> {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static <K, V> Map<K, V> of() {
|
||||
return (Map<K,V>) ImmutableCollections.MapN.EMPTY_MAP;
|
||||
return (Map<K,V>) ImmutableCollections.EMPTY_MAP;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1606,7 +1606,7 @@ public interface Map<K, V> {
|
||||
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
|
||||
if (entries.length == 0) { // implicit null check of entries array
|
||||
@SuppressWarnings("unchecked")
|
||||
var map = (Map<K,V>) ImmutableCollections.MapN.EMPTY_MAP;
|
||||
var map = (Map<K,V>) ImmutableCollections.EMPTY_MAP;
|
||||
return map;
|
||||
} else if (entries.length == 1) {
|
||||
// implicit null check of the array slot
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -450,7 +450,7 @@ public interface Set<E> extends Collection<E> {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static <E> Set<E> of() {
|
||||
return (Set<E>) ImmutableCollections.SetN.EMPTY_SET;
|
||||
return (Set<E>) ImmutableCollections.EMPTY_SET;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -694,7 +694,7 @@ public interface Set<E> extends Collection<E> {
|
||||
switch (elements.length) { // implicit null check of elements
|
||||
case 0:
|
||||
@SuppressWarnings("unchecked")
|
||||
var set = (Set<E>) ImmutableCollections.SetN.EMPTY_SET;
|
||||
var set = (Set<E>) ImmutableCollections.EMPTY_SET;
|
||||
return set;
|
||||
case 1:
|
||||
return new ImmutableCollections.Set12<>(elements[0]);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -91,11 +91,21 @@ public class ImmutableColls {
|
||||
public static final Map<String, String> fm3 = Map.copyOf(m3);
|
||||
public static final Map<String, String> fm4 = Map.copyOf(m4);
|
||||
|
||||
public static final List<String> fa0 = new ArrayList<>(l0);
|
||||
public static final List<String> fa1 = new ArrayList<>(l1);
|
||||
public static final List<String> fa2 = new ArrayList<>(l2);
|
||||
public static final List<String> fa3 = new ArrayList<>(l3);
|
||||
public static final List<String> fa4 = new ArrayList<>(l4);
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public void constructLists(Blackhole bh) {
|
||||
bh.consume(List.of(STRINGS[0]));
|
||||
bh.consume(List.of(STRINGS[0], STRINGS[1]));
|
||||
bh.consume(List.of(STRINGS[0], STRINGS[1], STRINGS[2]));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public void constructSets(Blackhole bh) {
|
||||
bh.consume(Set.of(STRINGS[0]));
|
||||
bh.consume(Set.of(STRINGS[0], STRINGS[1]));
|
||||
bh.consume(Set.of(STRINGS[0], STRINGS[1], STRINGS[2]));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
@ -109,7 +119,7 @@ public class ImmutableColls {
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public int finalSumSizesList() {
|
||||
public int sumSizesFinalList() {
|
||||
return sizeOf(fl0) +
|
||||
sizeOf(fl1) +
|
||||
sizeOf(fl2) +
|
||||
@ -119,32 +129,120 @@ public class ImmutableColls {
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public int sumSizesArrayList() {
|
||||
return sizeOf2(a0) +
|
||||
sizeOf2(a1) +
|
||||
sizeOf2(a2) +
|
||||
sizeOf2(a3) +
|
||||
sizeOf2(a4);
|
||||
public int sumSizesSet() {
|
||||
return sizeOf(s0) +
|
||||
sizeOf(s1) +
|
||||
sizeOf(s2) +
|
||||
sizeOf(s3) +
|
||||
sizeOf(s4);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public int finalSumSizesArrayList() {
|
||||
return sizeOf2(fa0) +
|
||||
sizeOf2(fa1) +
|
||||
sizeOf2(fa2) +
|
||||
sizeOf2(fa3) +
|
||||
sizeOf2(fa4);
|
||||
public int sumSizesFinalSet() {
|
||||
return sizeOf2(fs0) +
|
||||
sizeOf2(fs1) +
|
||||
sizeOf2(fs2) +
|
||||
sizeOf2(fs3) +
|
||||
sizeOf2(fs4);
|
||||
}
|
||||
|
||||
public int sizeOf2(List<String> list) {
|
||||
return list.size();
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public boolean emptyFinalSet() {
|
||||
return fs0.isEmpty() &
|
||||
fs1.isEmpty() &
|
||||
fs2.isEmpty() &
|
||||
fs3.isEmpty() &
|
||||
fs4.isEmpty();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public boolean emptyFinalList() {
|
||||
return fl0.isEmpty() &
|
||||
fl1.isEmpty() &
|
||||
fl2.isEmpty() &
|
||||
fl3.isEmpty() &
|
||||
fl4.isEmpty();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public boolean emptyFinalMap() {
|
||||
return fm0.isEmpty() &
|
||||
fm1.isEmpty() &
|
||||
fm2.isEmpty() &
|
||||
fm3.isEmpty() &
|
||||
fm4.isEmpty();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public boolean containsFinalSet() {
|
||||
return fs0.contains("hi") &
|
||||
fs1.contains("hi") &
|
||||
fs2.contains("hi") &
|
||||
fs3.contains("hi") &
|
||||
fs4.contains("hi");
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public boolean containsFinalList() {
|
||||
return fl0.contains("hi") &
|
||||
fl1.contains("hi") &
|
||||
fl2.contains("hi") &
|
||||
fl3.contains("hi") &
|
||||
fl4.contains("hi");
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public boolean containsKeyFinalMap() {
|
||||
return fm0.containsKey("hi") &
|
||||
fm1.containsKey("hi") &
|
||||
fm2.containsKey("hi") &
|
||||
fm3.containsKey("hi") &
|
||||
fm4.containsKey("hi");
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public boolean containsValueFinalMap() {
|
||||
return fm0.containsValue("hi") &
|
||||
fm1.containsValue("hi") &
|
||||
fm2.containsValue("hi") &
|
||||
fm3.containsValue("hi") &
|
||||
fm4.containsValue("hi");
|
||||
}
|
||||
|
||||
public int sizeOf(List<String> list) {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as sizeOf(List), but duplicated to avoid any
|
||||
* potential profile pollution with tests using
|
||||
* sizeOf.
|
||||
*/
|
||||
public int sizeOf2(List<String> list) {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public int sizeOf(Set<String> set) {
|
||||
return set.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as sizeOf(Set), but duplicated to avoid any
|
||||
* potential profile pollution with tests using
|
||||
* sizeOf.
|
||||
*/
|
||||
public int sizeOf2(Set<String> set) {
|
||||
return set.size();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public int getFromList() {
|
||||
@ -173,6 +271,22 @@ public class ImmutableColls {
|
||||
bh.consume(s0.toArray());
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public void iterateOverSet(Blackhole bh) {
|
||||
iterateSet(bh, fs4);
|
||||
iterateSet(bh, s1);
|
||||
iterateSet(bh, s3);
|
||||
iterateSet(bh, fs2);
|
||||
iterateSet(bh, s0);
|
||||
}
|
||||
|
||||
public void iterateSet(Blackhole bh, Set<String> coll) {
|
||||
for (String s : coll) {
|
||||
bh.consume(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public void toArrayFromMap(Blackhole bh) {
|
||||
@ -232,15 +346,6 @@ public class ImmutableColls {
|
||||
bh.consume(List.copyOf(fsl3));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
|
||||
public int finalGetFromArrayList() {
|
||||
return get2(fa1, 0).length() +
|
||||
get2(fa2, 1).length() +
|
||||
get2(fa3, 2).length() +
|
||||
get2(fa4, 3).length();
|
||||
}
|
||||
|
||||
public String get2(List<String> list, int idx) {
|
||||
return list.get(idx);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user