jamespud opened a new pull request, #16027:
URL: https://github.com/apache/dubbo/pull/16027

   - Optimize getBytes/setBytes/readBytes/writeBytes methods
   - Avoid intermediate byte array copy when source/destination is 
NettyBackedChannelBuffer
   - Directly use Netty's ByteBuf transfer capabilities
   - Add fallback to intermediate array copy for other ChannelBuffer 
implementations
   - Improve performance by 4-5x for Netty-to-Netty buffer transfers
   
   Below are test code:
   ```java
   import org.apache.dubbo.remoting.buffer.ByteBufferBackedChannelBuffer;
   import org.apache.dubbo.remoting.buffer.ChannelBuffer;
   import org.apache.dubbo.remoting.transport.netty4.NettyBackedChannelBuffer;
   import 
org.apache.dubbo.remoting.transport.netty4.NettyBackedChannelBufferOld;
   
   import java.nio.ByteBuffer;
   
   import io.netty.buffer.ByteBuf;
   import io.netty.buffer.PooledByteBufAllocator;
   import org.junit.jupiter.api.Test;
   
   public class NettyBackedChannelBufferBenchmarkTest {
   
       private static final int BUFFER_SIZE = 1024 * 1024; // 1MB
       private static final int TEST_ITERATIONS = 1000;
   
       @Test
       public void testPerformance() {
           byte[] data = new byte[BUFFER_SIZE];
           for (int i = 0; i < data.length; i++) {
               data[i] = (byte) (i % 256);
           }
   
           ByteBuf nettyBuffer = 
PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE);
           nettyBuffer.writeBytes(data);
           ChannelBuffer nettySource = new 
NettyBackedChannelBuffer(nettyBuffer);
   
           // Netty->Netty vs Netty->Other (getBytes)
           double nettyToNettyGet = testGetBytes(
                   nettySource, new 
NettyBackedChannelBuffer(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           double nettyToOtherGet = testGetBytes(
                   nettySource, new 
NettyBackedChannelBufferOld(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           System.out.printf(
                   "getBytes: Netty->Netty %.2f MB/s, Netty->Other %.2f MB/s, 
ratio %.2f\n",
                   nettyToNettyGet, nettyToOtherGet, (nettyToOtherGet > 0 ? 
nettyToNettyGet / nettyToOtherGet : 0.0));
   
           // Netty->Netty vs Netty->Other (setBytes)
           double nettyToNettySet = testSetBytes(
                   nettySource, new 
NettyBackedChannelBuffer(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           double nettyToOtherSet = testSetBytes(
                   nettySource, new 
NettyBackedChannelBufferOld(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           System.out.printf(
                   "setBytes: Netty->Netty %.2f MB/s, Netty->Other %.2f MB/s, 
ratio %.2f\n",
                   nettyToNettySet, nettyToOtherSet, (nettyToOtherSet > 0 ? 
nettyToNettySet / nettyToOtherSet : 0.0));
   
           System.out.println("-----------------------------------");
   
           ByteBufferBackedChannelBuffer byteBufferSource =
                   new 
ByteBufferBackedChannelBuffer(ByteBuffer.allocate(BUFFER_SIZE));
           
           if (byteBufferSource.readableBytes() < BUFFER_SIZE) {
               byteBufferSource.clear();
               byteBufferSource.writeBytes(data);
           }
   
           double otherToNettyGet = testGetBytes(
                   byteBufferSource, new 
NettyBackedChannelBuffer(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           double otherToOtherGet = testGetBytes(
                   byteBufferSource, new 
NettyBackedChannelBufferOld(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           System.out.printf(
                   "getBytes: Other->Netty %.2f MB/s, Other->Other %.2f MB/s, 
ratio %.2f\n",
                   otherToNettyGet, otherToOtherGet, (otherToOtherGet > 0 ? 
otherToNettyGet / otherToOtherGet : 0.0));
   
           double otherToNettySet = testSetBytes(
                   byteBufferSource, new 
NettyBackedChannelBuffer(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           double otherToOtherSet = testSetBytes(
                   byteBufferSource, new 
NettyBackedChannelBufferOld(PooledByteBufAllocator.DEFAULT.buffer(BUFFER_SIZE)));
           System.out.printf(
                   "setBytes: Other->Netty %.2f MB/s, Other->Other %.2f MB/s, 
ratio %.2f\n",
                   otherToNettySet, otherToOtherSet, (otherToOtherSet > 0 ? 
otherToNettySet / otherToOtherSet : 0.0));
   
           nettyBuffer.release();
       }
   
       private static double testGetBytes(ChannelBuffer src, ChannelBuffer 
dest) {
           if (src.readableBytes() < BUFFER_SIZE) {
               byte[] fill = new byte[BUFFER_SIZE];
               for (int i = 0; i < fill.length; i++) {
                   fill[i] = (byte) (i % 256);
               }
               src.clear();
               src.writeBytes(fill);
           }
   
           for (int i = 0; i < TEST_ITERATIONS / 10; i++) {
               dest.clear(); 
               src.getBytes(0, dest, 0, BUFFER_SIZE);
           }
   
           long startTime = System.nanoTime();
           for (int i = 0; i < TEST_ITERATIONS; i++) {
               dest.clear();
               src.getBytes(0, dest, 0, BUFFER_SIZE);
           }
           long endTime = System.nanoTime();
           long totalTime = endTime - startTime;
           
           dest.release();
   
           return TEST_ITERATIONS / (totalTime / 1_000_000_000.0);
       }
   
       private static double testSetBytes(ChannelBuffer src, ChannelBuffer 
dest) {
           if (src.readableBytes() < BUFFER_SIZE) {
               byte[] fill = new byte[BUFFER_SIZE];
               for (int i = 0; i < fill.length; i++) {
                   fill[i] = (byte) (i % 256);
               }
               src.clear();
               src.writeBytes(fill);
           }
   
           for (int i = 0; i < TEST_ITERATIONS / 10; i++) {
               dest.clear();
               dest.setBytes(0, src, 0, BUFFER_SIZE);
           }
   
           long startTime = System.nanoTime();
           for (int i = 0; i < TEST_ITERATIONS; i++) {
               dest.clear();
               dest.setBytes(0, src, 0, BUFFER_SIZE);
           }
           long endTime = System.nanoTime();
           long totalTime = endTime - startTime;
           
           dest.release();
   
           return TEST_ITERATIONS / (totalTime / 1_000_000_000.0);
       }
   }
   
   ```
   
   Test output:
   ```plain text
   getBytes: Netty->Netty 36047.87 MB/s, Netty->Other 6926.83 MB/s, ratio 5.20
   setBytes: Netty->Netty 49730.58 MB/s, Netty->Other 13129.59 MB/s, ratio 3.79
   -----------------------------------
   getBytes: Other->Netty 53048.21 MB/s, Other->Other 46807.54 MB/s, ratio 1.13
   setBytes: Other->Netty 11765.61 MB/s, Other->Other 11816.55 MB/s, ratio 1.00
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to