Closed dkropachev closed 1 week ago
What is the issue with synchronized? Old methods looks fine to me.
@nyh, @Bouncheck , please check one more time.
@Bouncheck , I somehow accidentially merged it, please let me know if you want to roll it back
Do we have numbers to show it improves performance?
Do we have numbers to show it improves performance?
Unfortunately java does not have built-in microbenchmark framework, and this repo does not have one as well.
So, having these test will require some effort.
I have created a naive benchmark that runs 100 threads, each thread runs 100000
nextAsURI
, old version completes test in 2752
ms, while new one in 802
, so it is 3+ times faster in given circumstances.
To be fair this test does not represent real scenario, rather extreme case, but it showcase congestion that can be created by exclusive locks on class instance, which sinchronize
is.
Test:
package com.scylladb.alternator;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class AlternatorLiveNodesBenchmark {
static public class MockAlternatorLiveNodes extends AlternatorLiveNodes {
private MockAlternatorLiveNodes() {
super("http", Arrays.asList("1.1.1.1"), 8080);
}
@Override
List<String> getNodesListFromURL(URI uri) throws IOException {
String[] tmp = {"1.1.1.2", "1.1.1.3", "1.1.1.4"};
return Arrays.asList(tmp);
}
}
public synchronized static void main(String[] args) {
Integer threads = 100;
Integer iterations = 100000;
AlternatorLiveNodes ln = new MockAlternatorLiveNodes();
ln.setDaemon(true);
ln.start();
List<Thread> th = new ArrayList<>();
for (Integer n = 0; n < threads; n++) {
th.add(new Thread(() -> {
for (int i = 0; i < iterations; i++) {
URI tmp = ln.nextAsURI();
}
}));
}
long startTime = System.currentTimeMillis();
th.forEach(Thread::start);
th.forEach(t -> {
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
long lasted = System.currentTimeMillis() - startTime;
System.out.println(String.format("done waiting - lasted %s", lasted));
System.exit(0);
}
}
Using
CopyOnWriteArrayList
andAtomicInteger
will provide more performance.