Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我不知道';我看不到干扰器的性能改进_Java_Disruptor Pattern_Lmax - Fatal编程技术网

Java 我不知道';我看不到干扰器的性能改进

Java 我不知道';我看不到干扰器的性能改进,java,disruptor-pattern,lmax,Java,Disruptor Pattern,Lmax,我知道我的问题与Disruptor API的基本主张背道而驰。但当我了解它时,我编写了一个程序来替换我使用ArrayLinkedBlockingQueue的1P-1C用例。但当我运行程序时,我不断得到disruptor比ArrayLinkedBlockingQueue更糟糕的总时间。我一定是做错了什么,或者测量错误了,但我不确定我的程序中有什么错误。有人有意见吗 (这是一个测试程序,显然我的EventHandler没有做任何事情) import java.util.concurrent.Arra

我知道我的问题与Disruptor API的基本主张背道而驰。但当我了解它时,我编写了一个程序来替换我使用ArrayLinkedBlockingQueue的1P-1C用例。但当我运行程序时,我不断得到disruptor比ArrayLinkedBlockingQueue更糟糕的总时间。我一定是做错了什么,或者测量错误了,但我不确定我的程序中有什么错误。有人有意见吗

(这是一个测试程序,显然我的EventHandler没有做任何事情)

import java.util.concurrent.ArrayBlockingQueue;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.ThreadPoolExecutor;
导入java.util.concurrent.TimeUnit;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入com.lmax.disruptor.BusySpinWaitStrategy;
导入com.lmax.disruptor.EventFactory;
导入com.lmax.disruptor.EventHandler;
导入com.lmax.disruptor.EventTranslator;
导入com.lmax.disruptor.RingBuffer;
导入com.lmax.disruptor.dsl.disruptor;
导入com.lmax.disruptor.dsl.ProducerType;
公共类SPSCDISRUPTERTEST{
专用静态最终整数单位_SIZE=1024;
私有静态最终整数缓冲区大小=单位大小*1024*16;
私有静态最终整数迭代=缓冲区大小;
专用静态最终记录器记录器=记录器工厂
.getLogger(SPSCDisruptertest.class);
私有静态类数据{
私有字符串数据;
公共字符串getData(){
返回数据;
}
公共void setData(字符串数据){
这个数据=数据;
}
@凌驾
公共字符串toString(){
返回“Data[Data=“+Data+”]”;
}
public final static EventFactory DATA\u FACTORY=new EventFactory(){
@凌驾
公共数据newInstance(){
返回新数据();
}
};
}
私有静态类DataEventTranslator实现EventTranslator{
专用字符串有效载荷;
公共DataEventTranslator(字符串负载){
这个有效载荷=有效载荷;
}
@凌驾
public void translateTo(数据d,长序列){
d、 setData(有效载荷);
}
};
公共静态void main(字符串[]args)引发InterruptedException{
新的SPSCDisruptorTest().testDisruptor();
新的SPSCDisruptorTest().testExecutor();
}
@抑制警告(“未选中”)
公共void testDisruptor(){
ExecutorService exec=Executors.newSingleThreadExecutor();
干扰物干扰物=新干扰物(
SPSCDISRUPTRTEST.Data.Data工厂,缓冲区大小,exec,
ProducerType.SINGLE,新BusySpinWaitStrategy());
disruptor.handleEventsWith(新的EventHandler(){
@凌驾
public void onEvent(数据、长序列、布尔endOfBatch)
抛出异常{
}
});
long t1=System.nanoTime();
RingBuffer=disruptor.start();

对于(int i=1;i您实际上测量错误。您应该在启动中断器后开始测量,因为它在预热过程中需要时间(分配环形缓冲区)。由于您的缓冲区大小非常大,因此在预热过程中需要相当长的时间。请尝试下面的示例代码。它会给您更好的时间

    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);
RingBuffer=disruptor.start();
long t1=System.nanoTime();

对于(int i=1;i您没有足够的争用来显示无锁中断器的帮助。特别是,您的执行器队列与迭代次数一样大!所有数据都适合执行器队列,因此它基本上从不在notempty/notfull条件下运行

Executor服务也非常糟糕,因为如果队列较小,您会拒绝执行。您需要比较的是两个线程的有限队列(可能1000长)和阻塞.put()/.take()调用


更糟糕的是,您需要成批的数据(而不是一个接一个)还有许多读者,甚至可能是许多作者。在executor测试中使用争用队列访问,中断器应该可以毫无问题地显示其性能。

我在我的机器上尝试过你的代码,每次使用中断器都能获得更好的结果。我使用了更小的缓冲区,但遗憾的是,我没有看到太大的差异。与旧ap相比方法中断器所用时间:2.93E7毫秒,在中断器.start()之后跟踪时间,我得到了2.6E7毫秒,所以差别不大。。。
    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);