package org.ireland.jnetty.buffer; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import io.netty.buffer.Unpooled; import org.junit.BeforeClass; import org.junit.Test; /** * 模拟HttpServletResponseImpl的输出测试 * @author KEN * */ public class UnpooledPkPolledTest { //假设数据: 128Byte 一行 private static byte[] src = "<a id='nav-shop-all-button' href='/gp/site-directory' class='nav_a nav-button-outer nav-menu-inactive' alt='全部商品分类'>".getBytes(); //10K 个请求每秒 private static int RPS = 10 * 1000; //模拟10次 private static int LOOP = 10; /** * UnpooledHeapByteBuf: 内部用byte[]来存放数据,当当前byte数组长度不足以存放 待写入的数据时, * 则新建一个长度为原来byte数据长度2部的数组,然后利用 System.arraycopy(...)复制数据, * 会造成性能下降 和 增加GC压力 * * 128B >> 256B >> 512B >> 1KB >> 2KB >> 4KB >> 8KB >> 16KB >> 32KB >> 64KB >> 128KB >> 256KB * * 逐行输入的方式来输出一个256KB的页面,其中在新建 和 数组复制的操作 达 12次 .... * * */ @BeforeClass public static void init() { Unpooled.buffer(0); PooledByteBufAllocator.DEFAULT.directBuffer(0); } @Test//24.288S public void test_UnpooledHeapByteBuf() { long start = System.currentTimeMillis(); for(int i=0; i<RPS * LOOP; i++) { ByteBuf byteBuf = Unpooled.buffer(0); writeHtmlPage(byteBuf); } long ms = System.currentTimeMillis() - start; System.out.println("UnpooledHeapByteBuf:每10K请求耗时: "+ms/(RPS) + "(ms)"); //每10K请求耗时: 2(ms) } /** * PooledUnsafeDirectByteBuf: 内部预分配的DirectByteBuffer 数据块 来存放数据 * * 128B >> 256B >> 512B >> 1KB >> 2KB >> 4KB >> 8KB >> 16KB >> 32KB >> 64KB >> 128KB >> 256KB * * 逐行输入的方式来输出一个256KB的页面,其中PlatformDependent.copyMemory 进行 复制的操作 达 12次 .... * * PlatformDependent.copyMemory * * 尽管和UnpooledHeapByteBuf一样要进行多次的数据复制,但PooledUnsafeDirectByteBuf的数据空间是预先开辟的,是池化的, * 而UnpooledHeapByteBuf是未池化的,要用到的时候才开辟,性能较差 * * TODO: 能否开发出 (池化+组合)的ByteBuf,免去大量的中间数据的复制开销?? * */ @Test//18.335s public void test_PooledUnsafeDirectByteBuf() { long start = System.currentTimeMillis(); for(int i=0; i<RPS * LOOP; i++) { ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(0); writeHtmlPage(byteBuf); } long ms = System.currentTimeMillis() - start; System.out.println("PooledUnsafeDirectByteBuf:每10K请求耗时: "+ms/(RPS) + "(ms)"); //每10K请求耗时: 2(ms) } @Test//18.968s public void test_PooledHeapByteBuf() { long start = System.currentTimeMillis(); for(int i=0; i<RPS * LOOP; i++) { ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.heapBuffer(0); writeHtmlPage(byteBuf); } long ms = System.currentTimeMillis() - start; System.out.println("PooledHeapByteBuf:每10K请求耗时: "+ms/(RPS) + "(ms)"); //每10K请求耗时: 2(ms) } /** * 页面大小参考京东: 256KB = 128Byte/行 * 2048行 * @param byteBuf */ public void writeHtmlPage(ByteBuf byteBuf) { for(int j = 0; j<2048; j++) byteBuf.writeBytes(src); byteBuf.release(); } }