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({
41              "1",
42              "2",
43              "3",
44              "4",
45              "7",
46              "8",
47              "15",
48              "64",
49              "65",
50              "1024",
51      })
52      private int bytes = 1024;
53      @Param({
54              "true",
55              "false",
56      })
57      private boolean direct;
58      @Param({
59              "true",
60              "false",
61      })
62      private boolean pooled;
63      @Param({
64              "false",
65      })
66      public String checkAccessible;
67  
68      @Param({
69              "false",
70      })
71      public String checkBounds;
72      @Param({
73              "0",
74              "1",
75      })
76      public int startOffset;
77      private ByteBuf buffer;
78      private int offset;
79  
80      @Setup
81      public void setup() {
82          System.setProperty("io.netty.buffer.checkAccessible", checkAccessible);
83          System.setProperty("io.netty.buffer.checkBounds", checkBounds);
84          ByteBufAllocator allocator = pooled? PooledByteBufAllocator.DEFAULT : UnpooledByteBufAllocator.DEFAULT;
85          int capacityRequired = startOffset + bytes;
86          offset = 0;
87          buffer = direct? alignedDirectAllocation(allocator, capacityRequired, 8) :
88                  allocator.heapBuffer(capacityRequired, capacityRequired);
89          if (startOffset > 0) {
90              offset += startOffset;
91          }
92      }
93  
94      private ByteBuf alignedDirectAllocation(ByteBufAllocator allocator, int bytes, final int alignment) {
95          ByteBuf buffer = allocator.directBuffer(bytes + alignment, bytes + alignment);
96          final long address = buffer.memoryAddress();
97          final int remainder = (int) address % alignment;
98          final int nextAlignedOffset = alignment - remainder;
99          this.offset = nextAlignedOffset;
100         return buffer;
101     }
102 
103     @Benchmark
104     public ByteBuf setZero() {
105         final ByteBuf buffer = this.buffer;
106         buffer.setZero(offset, bytes);
107         return buffer;
108     }
109 
110     @Benchmark
111     public ByteBuf setBytes() {
112         final ByteBuf buffer = this.buffer;
113         final int offset = this.offset;
114         for (int i = 0; i < bytes; i++) {
115             buffer.setByte(offset + i, 0);
116         }
117         return buffer;
118     }
119 
120     @TearDown
121     public void teardown() {
122         buffer.release();
123     }
124 
125 }