![](/img/trans.png)
[英]Why my Disruptor program don't take full advantage of the ringbuffer
[英]I don't see the performance improvement of Disruptor
我知道我的问题与Disruptor API的根本主张背道而驰。 但是,当我学习它时,我写了一个程序来替换我在使用ArrayLinkedBlockingQueue的1P-1C用例。 但是,当我运行程序时,与ArrayLinkedBlockingQueue相比,我使干扰器花费的总时间更糟。 我一定做错了或度量错误,但是我不确定程序中的内容。 有人有意见吗?
(这是一个测试程序,因此显然我的EventHandler没有执行任何操作)
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.EventTranslator;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
public class SPSCDisruptorTest {
private static final int UNIT_SIZE = 1024;
private static final int BUFFER_SIZE = UNIT_SIZE * 1024 * 16;
private static final int ITERATIONS = BUFFER_SIZE;
private static final Logger logger = LoggerFactory
.getLogger(SPSCDisruptorTest.class);
private static class Data {
private String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Override
public String toString() {
return "Data [data=" + data + "]";
}
public final static EventFactory<Data> DATA_FACTORY = new EventFactory<Data>() {
@Override
public Data newInstance() {
return new Data();
}
};
}
private static class DataEventTranslator implements EventTranslator<Data> {
private String payload;
public DataEventTranslator(String payload) {
this.payload = payload;
}
@Override
public void translateTo(Data d, long sequence) {
d.setData(payload);
}
};
public static void main(String[] args) throws InterruptedException {
new SPSCDisruptorTest().testDisruptor();
new SPSCDisruptorTest().testExecutor();
}
@SuppressWarnings("unchecked")
public void testDisruptor() {
ExecutorService exec = Executors.newSingleThreadExecutor();
Disruptor<Data> disruptor = new Disruptor<Data>(
SPSCDisruptorTest.Data.DATA_FACTORY, BUFFER_SIZE, exec,
ProducerType.SINGLE, new BusySpinWaitStrategy());
disruptor.handleEventsWith(new EventHandler<Data>() {
@Override
public void onEvent(Data data, long sequence, boolean endOfBatch)
throws Exception {
}
});
long t1 = System.nanoTime();
RingBuffer<Data> buffer = disruptor.start();
for (int i = 1; i <= ITERATIONS; i++) {
buffer.publishEvent(new DataEventTranslator("data" + i));
}
logger.info("waiting for shutdown");
disruptor.shutdown();
logger.info("Disruptor Time (ms): " + (System.nanoTime() - t1 * 1.0)
/ 1000);
logger.info("Disruptor is shutdown");
exec.shutdown();
}
public void testExecutor() throws InterruptedException {
ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L,
TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(
BUFFER_SIZE));
long t1 = System.nanoTime();
for (int i = 1; i <= ITERATIONS; i++) {
executor.submit(new DataRunner("data" + i));
}
executor.shutdown();
executor.awaitTermination(5000, TimeUnit.SECONDS);
logger.info("Executor Time (ms): " + (System.nanoTime() - t1 * 1.0)
/ 1000);
}
private static class DataRunner implements Runnable {
private String data;
public DataRunner(String data) {
this.data = data;
}
@Override
public void run() {
}
}
}
您实际上是在测量错误。 启动干扰器后,应该开始测量,因为它需要花费一些时间进行预热(分配环形缓冲区)。 由于缓冲区很大,因此预热需要花费大量时间。 请尝试下面的示例代码。 它应该给您更好的时间。
RingBuffer<Data> buffer = disruptor.start();
long t1 = System.nanoTime();
for (int i = 1; i <= ITERATIONS; i++) {
buffer.publishEvent(new DataEventTranslator("data" + i));
}
logger.info("waiting for shutdown");
disruptor.shutdown();
logger.info("Disruptor Time (ms): " + (System.nanoTime() - t1 * 1.0)
/ 1000);
您没有足够的争论来说明无锁干扰器如何提供帮助。 特别是,您的执行者队列与迭代一样大! 所有数据都适合执行程序队列,因此它基本上绝不会在非空/非满条件下运行。
执行器服务也确实很糟糕,因为如果队列较小,您将拒绝执行。 您需要比较的是2个线程和一个有限队列(可能长1000)并阻塞了.put()/。take()调用。
更糟糕的是,您需要成批的数据(而不是1比1),并且需要许多读者,甚至可能需要很多作家。 通过对执行程序测试进行竞争的队列访问,中断程序应该毫无问题地显示其性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.