github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/util/string_helper_test.go (about)

     1  // Copyright 2022 iLogtail Authors
     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 util
    16  
    17  import (
    18  	"github.com/stretchr/testify/assert"
    19  
    20  	"testing"
    21  	"unsafe"
    22  )
    23  
    24  func TestZeroCopyString(t *testing.T) {
    25  	slice := []byte("jkdfjksdfj")
    26  	newStr := ZeroCopyBytesToString(slice)
    27  	bytes := *(*[]byte)(unsafe.Pointer(&newStr))
    28  	assert.Equal(t, &bytes[0], &slice[0])
    29  }
    30  
    31  func TestZeroCopySlice(t *testing.T) {
    32  	str := "dfdsfdsf"
    33  	bytes := *(*[]byte)(unsafe.Pointer(&str))
    34  	slice := ZeroCopyStringToBytes(str)
    35  	assert.Equal(t, &bytes[0], &slice[0])
    36  }
    37  
    38  func TestZeroCopyStringNil(t *testing.T) {
    39  	newStr := ZeroCopyBytesToString(nil)
    40  	newStr2 := ZeroCopyBytesToString([]byte(""))
    41  	assert.Equal(t, newStr, newStr2)
    42  }
    43  
    44  func TestZeroCopySliceEmpty(t *testing.T) {
    45  	str := ""
    46  	bytes := *(*[]byte)(unsafe.Pointer(&str))
    47  	slice := ZeroCopyStringToBytes(str)
    48  	assert.Equal(t, &bytes, &slice)
    49  }
    50  
    51  // goos: darwin
    52  // goarch: amd64
    53  // pkg: github.com/alibaba/ilogtail/pkg/helper
    54  // cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    55  // BenchmarkZeroCopyString
    56  // BenchmarkZeroCopyString/no-zero-copy
    57  // BenchmarkZeroCopyString/no-zero-copy-12                 59734488                20.07 ns/op           16 B/op          1 allocs/op
    58  // BenchmarkZeroCopyString/zero-copy
    59  // BenchmarkZeroCopyString/zero-copy-12                    474650650                2.515 ns/op           0 B/op          0 allocs/op
    60  func BenchmarkZeroCopyString(b *testing.B) {
    61  	slice := []byte("jkdfjksdfj")
    62  	tests := []struct {
    63  		name string
    64  		fun  func() string
    65  	}{
    66  		{
    67  			"no-zero-copy",
    68  			func() string {
    69  				return string(slice)
    70  			},
    71  		},
    72  		{
    73  			"zero-copy",
    74  			func() string {
    75  				return ZeroCopyBytesToString(slice)
    76  			},
    77  		},
    78  	}
    79  	for _, tt := range tests {
    80  		b.Run(tt.name, func(b *testing.B) {
    81  			for i := 0; i < b.N; i++ {
    82  				tt.fun()
    83  			}
    84  		})
    85  	}
    86  }
    87  
    88  // goos: darwin
    89  // goarch: amd64
    90  // pkg: github.com/alibaba/ilogtail/pkg/helper
    91  // cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    92  // BenchmarkZeroCopySlice
    93  // BenchmarkZeroCopySlice/no-zero-copy
    94  // BenchmarkZeroCopySlice/no-zero-copy-12                  48458805                23.11 ns/op           16 B/op          1 allocs/op
    95  // BenchmarkZeroCopySlice/zero-copy
    96  // BenchmarkZeroCopySlice/zero-copy-12                     430296753                2.712 ns/op           0 B/op          0 allocs/op
    97  func BenchmarkZeroCopySlice(b *testing.B) {
    98  	str := "dfadsfadsf"
    99  	tests := []struct {
   100  		name string
   101  		fun  func() []byte
   102  	}{
   103  		{
   104  			"no-zero-copy",
   105  			func() []byte {
   106  				return []byte(str)
   107  			},
   108  		},
   109  		{
   110  			"zero-copy",
   111  			func() []byte {
   112  				return ZeroCopyStringToBytes(str)
   113  			},
   114  		},
   115  	}
   116  	for _, tt := range tests {
   117  		b.Run(tt.name, func(b *testing.B) {
   118  			for i := 0; i < b.N; i++ {
   119  				tt.fun()
   120  			}
   121  		})
   122  	}
   123  }
   124  
   125  func TestIsSafeString(t *testing.T) {
   126  	str1 := "123456"
   127  	str2 := "123"
   128  	unsafeStr := ZeroCopyBytesToString(ZeroCopyStringToBytes(str1)[:4])
   129  	assert.True(t, IsSafeString(str2, str1))
   130  	assert.False(t, IsSafeString(str1, unsafeStr))
   131  	assert.False(t, IsSafeString(unsafeStr, str1))
   132  }