mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
attempt to fix test blinking tests
avoid using THashMap / THashSet when Map / Set is intensively updated:
with multiple tombstones the cost of accessing map maybe linear.
For the record here is small example:
public void testProgressPerformance() {
// Int values + code to produce nontrivial empty THashMap nearly completely filled with deleted tombstones
// THash.compactIfNecessary limits compaction on deletion to hashes larger than MAGIC_VALUE = 42
int max = 29; // THash's initialCapacity that will produce Object[37], 37 < MAGIC_VALUE
class IdBackedEmptyProgressIndicator extends EmptyProgressIndicator {
final int myId;
IdBackedEmptyProgressIndicator(int id) { myId = id; }
@Override public int hashCode() { return myId; }
@Override public boolean equals(Object obj) {
if (!(obj instanceof IdBackedEmptyProgressIndicator)) return false;
return myId == ((IdBackedEmptyProgressIndicator)obj).myId;
}
}
for(int i = 0; i < max; ++i) {
CoreProgressManager.threadsUnderIndicator.put(new IdBackedEmptyProgressIndicator(i), Collections.emptySet());
}
for(int i = 0; i < max ; ++i) {
CoreProgressManager.threadsUnderIndicator.remove(new IdBackedEmptyProgressIndicator(i));
}
// THashMap in CoreProgressManager.threadsUnderIndicator has 29 tombstones
Random random = new Random(2);
for(int i = 0; i < 2 * max; ++i) {
IdBackedEmptyProgressIndicator key = new IdBackedEmptyProgressIndicator(random.nextInt());
CoreProgressManager.threadsUnderIndicator.put(key, Collections.emptySet());
CoreProgressManager.threadsUnderIndicator.remove(key);
}
// THashMap in CoreProgressManager.threadsUnderIndicator has 36 tombstones,
// 33th slot is free, more removals will cause rehash / clear of tombstones
PlatformTestUtil.startPerformanceTest("executeProcessUnderProgress", 100, () -> {
EmptyProgressIndicator indicator = new IdBackedEmptyProgressIndicator(16); // hash 16 will hit missing element 33 at 37th iteration
for (int i=0;i<100000;i++) {
ProgressManager.getInstance().executeProcessUnderProgress(EmptyRunnable.getInstance(), indicator);
}
}).assertTiming();
}
This commit is contained in:
@@ -19,8 +19,6 @@ import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.containers.ConcurrentLongObjectMap;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -46,13 +44,15 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
|
||||
private ScheduledFuture<?> myCheckCancelledFuture; // guarded by threadsUnderIndicator
|
||||
|
||||
// indicator -> threads which are running under this indicator. guarded by threadsUnderIndicator.
|
||||
private static final Map<ProgressIndicator, Set<Thread>> threadsUnderIndicator = new THashMap<>();
|
||||
// THashMap is avoided here because of tombstones overhead
|
||||
static final Map<ProgressIndicator, Set<Thread>> threadsUnderIndicator = new HashMap<>();
|
||||
// the active indicator for the thread id
|
||||
private static final ConcurrentLongObjectMap<ProgressIndicator> currentIndicators = ContainerUtil.createConcurrentLongObjectMap();
|
||||
// top-level indicators for the thread id
|
||||
private static final ConcurrentLongObjectMap<ProgressIndicator> threadTopLevelIndicators = ContainerUtil.createConcurrentLongObjectMap();
|
||||
// threads which are running under canceled indicator
|
||||
static final Set<Thread> threadsUnderCanceledIndicator = new THashSet<>(); // guarded by threadsUnderIndicator
|
||||
// THashSet is avoided here because of possible tombstones overhead
|
||||
static final Set<Thread> threadsUnderCanceledIndicator = new HashSet<>(); // guarded by threadsUnderIndicator
|
||||
private static volatile boolean shouldCheckCanceled;
|
||||
|
||||
/** active (i.e. which have {@link #executeProcessUnderProgress(Runnable, ProgressIndicator)} method running) indicators
|
||||
|
||||
Reference in New Issue
Block a user