github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/util/xxhash3/performance_test.go (about)

     1  // Copyright 2021 ByteDance Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package xxhash3
    16  
    17  import (
    18  	"runtime"
    19  	"testing"
    20  )
    21  
    22  type benchTask struct {
    23  	name      string
    24  	version   int
    25  	action    func(b []byte) uint64
    26  	action128 func(b []byte) [2]uint64
    27  }
    28  
    29  func BenchmarkDefault(b *testing.B) {
    30  	all := []benchTask{{
    31  		name: "Target64", version: 64, action: func(b []byte) uint64 {
    32  			return Hash(b)
    33  		}}, {
    34  		name: "Target128", version: 128, action128: func(b []byte) [2]uint64 {
    35  			return Hash128(b)
    36  		}},
    37  	}
    38  
    39  	benchLen0_16(b, all)
    40  	benchLen17_128(b, all)
    41  	benchLen129_240(b, all)
    42  	benchLen241_1024(b, all)
    43  	benchScalar(b, all)
    44  	benchAVX2(b, all)
    45  	benchSSE2(b, all)
    46  }
    47  
    48  func benchLen0_16(b *testing.B, benchTasks []benchTask) {
    49  	for _, v := range benchTasks {
    50  		b.Run("Len0_16/"+v.name, func(b *testing.B) {
    51  			b.ResetTimer()
    52  			for n := 0; n < b.N; n++ {
    53  				for i := 0; i <= 16; i++ {
    54  					input := dat[b.N : b.N+i]
    55  					if v.version == 64 {
    56  						a := v.action(input)
    57  						runtime.KeepAlive(a)
    58  					} else {
    59  						a := v.action128(input)
    60  						runtime.KeepAlive(a)
    61  					}
    62  				}
    63  			}
    64  		})
    65  	}
    66  }
    67  
    68  func benchLen17_128(b *testing.B, benchTasks []benchTask) {
    69  	for _, v := range benchTasks {
    70  		b.Run("Len17_128/"+v.name, func(b *testing.B) {
    71  			b.ResetTimer()
    72  			for n := 0; n < b.N; n++ {
    73  				for i := 17; i <= 128; i++ {
    74  					input := dat[b.N : b.N+i]
    75  					if v.version == 64 {
    76  						a := v.action(input)
    77  						runtime.KeepAlive(a)
    78  					} else {
    79  						a := v.action128(input)
    80  						runtime.KeepAlive(a)
    81  					}
    82  				}
    83  			}
    84  		})
    85  	}
    86  }
    87  
    88  func benchLen129_240(b *testing.B, benchTasks []benchTask) {
    89  	for _, v := range benchTasks {
    90  		b.Run("Len129_240/"+v.name, func(b *testing.B) {
    91  			b.ResetTimer()
    92  			for n := 0; n < b.N; n++ {
    93  				for i := 129; i <= 240; i++ {
    94  					input := dat[b.N : b.N+i]
    95  					if v.version == 64 {
    96  						a := v.action(input)
    97  						runtime.KeepAlive(a)
    98  					} else {
    99  						a := v.action128(input)
   100  						runtime.KeepAlive(a)
   101  					}
   102  				}
   103  			}
   104  		})
   105  	}
   106  }
   107  
   108  func benchLen241_1024(b *testing.B, benchTasks []benchTask) {
   109  	avx2, sse2 = false, false
   110  	for _, v := range benchTasks {
   111  		b.Run("Len241_1024/"+v.name, func(b *testing.B) {
   112  			b.ResetTimer()
   113  			for n := 0; n < b.N; n++ {
   114  				for i := 241; i <= 1024; i++ {
   115  					input := dat[b.N : b.N+i]
   116  					if v.version == 64 {
   117  						a := v.action(input)
   118  						runtime.KeepAlive(a)
   119  					} else {
   120  						a := v.action128(input)
   121  						runtime.KeepAlive(a)
   122  					}
   123  				}
   124  			}
   125  		})
   126  	}
   127  }
   128  
   129  func benchScalar(b *testing.B, benchTasks []benchTask) {
   130  	avx2, sse2 = false, false
   131  	for _, v := range benchTasks {
   132  		b.Run("Scalar/"+v.name, func(b *testing.B) {
   133  			b.ResetTimer()
   134  			for n := 0; n < b.N; n++ {
   135  				input := dat[n:33554432]
   136  				if v.version == 64 {
   137  					a := v.action(input)
   138  					runtime.KeepAlive(a)
   139  				} else {
   140  					a := v.action128(input)
   141  					runtime.KeepAlive(a)
   142  				}
   143  			}
   144  		})
   145  	}
   146  }
   147  
   148  func benchAVX2(b *testing.B, benchTasks []benchTask) {
   149  	avx2, sse2 = true, false
   150  	for _, v := range benchTasks {
   151  		b.Run("AVX2/"+v.name, func(b *testing.B) {
   152  			b.ResetTimer()
   153  			for n := 0; n < b.N; n++ {
   154  				input := dat[n:33554432]
   155  				if v.version == 64 {
   156  					a := v.action(input)
   157  					runtime.KeepAlive(a)
   158  				} else {
   159  					a := v.action128(input)
   160  					runtime.KeepAlive(a)
   161  				}
   162  			}
   163  		})
   164  	}
   165  }
   166  func benchSSE2(b *testing.B, benchTasks []benchTask) {
   167  	avx2, sse2 = false, true
   168  	for _, v := range benchTasks {
   169  		b.Run("SSE2/"+v.name, func(b *testing.B) {
   170  			b.ResetTimer()
   171  			for n := 0; n < b.N; n++ {
   172  				input := dat[n:33554432]
   173  				if v.version == 64 {
   174  					a := v.action(input)
   175  					runtime.KeepAlive(a)
   176  				} else {
   177  					a := v.action128(input)
   178  					runtime.KeepAlive(a)
   179  				}
   180  			}
   181  		})
   182  	}
   183  }