View Javadoc
1   /*
2    * Copyright 2023 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.buffer;
17  
18  import io.netty.microbench.util.AbstractMicrobenchmark;
19  import org.openjdk.jmh.annotations.Benchmark;
20  import org.openjdk.jmh.annotations.BenchmarkMode;
21  import org.openjdk.jmh.annotations.Measurement;
22  import org.openjdk.jmh.annotations.Mode;
23  import org.openjdk.jmh.annotations.OutputTimeUnit;
24  import org.openjdk.jmh.annotations.Param;
25  import org.openjdk.jmh.annotations.Scope;
26  import org.openjdk.jmh.annotations.Setup;
27  import org.openjdk.jmh.annotations.State;
28  import org.openjdk.jmh.annotations.TearDown;
29  import org.openjdk.jmh.annotations.Warmup;
30  
31  import java.util.concurrent.TimeUnit;
32  
33  @State(Scope.Benchmark)
34  @BenchmarkMode(Mode.AverageTime)
35  @OutputTimeUnit(TimeUnit.NANOSECONDS)
36  @Warmup(iterations = 10, time = 400, timeUnit = TimeUnit.MILLISECONDS)
37  @Measurement(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)
38  public class ByteBufZeroingBenchmark extends AbstractMicrobenchmark {
39  
40      @Param({ "1", "2", "3", "4", "7", "8", "15", "64", "65", "1024" })
41      private int bytes = 1024;
42      @Param({ "true", "false" })
43      private boolean direct;
44      @Param({ "true", "false" })
45      private boolean pooled;
46      @Param({ "false" })
47      public String checkAccessible;
48  
49      @Param({ "false" })
50      public String checkBounds;
51      @Param({ "0", "1" })
52      public int startOffset;
53      private ByteBuf buffer;
54      private int offset;
55  
56      @Setup
57      public void setup() {
58          System.setProperty("io.netty.buffer.checkAccessible", checkAccessible);
59          System.setProperty("io.netty.buffer.checkBounds", checkBounds);
60          ByteBufAllocator allocator = pooled? PooledByteBufAllocator.DEFAULT : UnpooledByteBufAllocator.DEFAULT;
61          int capacityRequired = startOffset + bytes;
62          offset = 0;
63          buffer = direct? alignedDirectAllocation(allocator, capacityRequired, 8) :
64                  allocator.heapBuffer(capacityRequired, capacityRequired);
65          if (startOffset > 0) {
66              offset += startOffset;
67          }
68      }
69  
70      private ByteBuf alignedDirectAllocation(ByteBufAllocator allocator, int bytes, final int alignment) {
71          ByteBuf buffer = allocator.directBuffer(bytes + alignment, bytes + alignment);
72          final long address = buffer.memoryAddress();
73          final int remainder = (int) address % alignment;
74          final int nextAlignedOffset = alignment - remainder;
75          this.offset = nextAlignedOffset;
76          return buffer;
77      }
78  
79      @Benchmark
80      public ByteBuf setZero() {
81          final ByteBuf buffer = this.buffer;
82          buffer.setZero(offset, bytes);
83          return buffer;
84      }
85  
86      @Benchmark
87      public ByteBuf setBytes() {
88          final ByteBuf buffer = this.buffer;
89          final int offset = this.offset;
90          for (int i = 0; i < bytes; i++) {
91              buffer.setByte(offset + i, 0);
92          }
93          return buffer;
94      }
95  
96      @TearDown
97      public void teardown() {
98          buffer.release();
99      }
100 
101 }