feat: add protobuf message compression and decompression for Redis; refactor product fetching logic
This commit is contained in:
		
							
								
								
									
										112
									
								
								cmd/test/slice_ptrs_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								cmd/test/slice_ptrs_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Большая структура для теста
 | 
			
		||||
type BigStruct struct {
 | 
			
		||||
	A, B, C, D, E, F, G, H, I, J float64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Обычные функции для слайсов структур
 | 
			
		||||
func ToPtrsStruct(s []BigStruct) []*BigStruct {
 | 
			
		||||
	res := make([]*BigStruct, len(s))
 | 
			
		||||
	for i := range s {
 | 
			
		||||
		res[i] = &s[i]
 | 
			
		||||
	}
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DerefSliceStruct(s []*BigStruct) []BigStruct {
 | 
			
		||||
	res := make([]BigStruct, len(s))
 | 
			
		||||
	for i := range s {
 | 
			
		||||
		if s[i] != nil {
 | 
			
		||||
			res[i] = *s[i]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unsafe версии
 | 
			
		||||
func ToPtrsStructUnsafe(s []BigStruct) []*BigStruct {
 | 
			
		||||
	n := len(s)
 | 
			
		||||
	res := make([]*BigStruct, n)
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		return res
 | 
			
		||||
	}
 | 
			
		||||
	base := unsafe.Pointer(&s[0])
 | 
			
		||||
	size := unsafe.Sizeof(s[0])
 | 
			
		||||
	for i := 0; i < n; i++ {
 | 
			
		||||
		res[i] = (*BigStruct)(unsafe.Pointer(uintptr(base) + uintptr(i)*size))
 | 
			
		||||
	}
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DerefSliceStructUnsafe(s []*BigStruct) []BigStruct {
 | 
			
		||||
	n := len(s)
 | 
			
		||||
	res := make([]BigStruct, n)
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		return res
 | 
			
		||||
	}
 | 
			
		||||
	baseDst := unsafe.Pointer(&res[0])
 | 
			
		||||
	size := unsafe.Sizeof(res[0])
 | 
			
		||||
	for i := 0; i < n; i++ {
 | 
			
		||||
		src := unsafe.Pointer(s[i])
 | 
			
		||||
		dst := unsafe.Pointer(uintptr(baseDst) + uintptr(i)*size)
 | 
			
		||||
		*(*BigStruct)(dst) = *(*BigStruct)(src)
 | 
			
		||||
	}
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// === Бенчмарки ===
 | 
			
		||||
func BenchmarkToPtrsStruct(b *testing.B) {
 | 
			
		||||
	data := make([]BigStruct, 1_000_000)
 | 
			
		||||
	for i := range data {
 | 
			
		||||
		data[i] = BigStruct{float64(i), float64(i), float64(i), float64(i),
 | 
			
		||||
			float64(i), float64(i), float64(i), float64(i), float64(i), float64(i)}
 | 
			
		||||
	}
 | 
			
		||||
	b.ResetTimer()
 | 
			
		||||
	for i := 0; i < b.N; i++ {
 | 
			
		||||
		_ = ToPtrsStruct(data)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkToPtrsStructUnsafe(b *testing.B) {
 | 
			
		||||
	data := make([]BigStruct, 1_000_000)
 | 
			
		||||
	for i := range data {
 | 
			
		||||
		data[i] = BigStruct{float64(i), float64(i), float64(i), float64(i),
 | 
			
		||||
			float64(i), float64(i), float64(i), float64(i), float64(i), float64(i)}
 | 
			
		||||
	}
 | 
			
		||||
	b.ResetTimer()
 | 
			
		||||
	for i := 0; i < b.N; i++ {
 | 
			
		||||
		_ = ToPtrsStructUnsafe(data)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkDerefSliceStruct(b *testing.B) {
 | 
			
		||||
	data := make([]BigStruct, 1_000_000)
 | 
			
		||||
	for i := range data {
 | 
			
		||||
		data[i] = BigStruct{float64(i), float64(i), float64(i), float64(i),
 | 
			
		||||
			float64(i), float64(i), float64(i), float64(i), float64(i), float64(i)}
 | 
			
		||||
	}
 | 
			
		||||
	ptrs := ToPtrsStruct(data)
 | 
			
		||||
	b.ResetTimer()
 | 
			
		||||
	for i := 0; i < b.N; i++ {
 | 
			
		||||
		_ = DerefSliceStruct(ptrs)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkDerefSliceStructUnsafe(b *testing.B) {
 | 
			
		||||
	data := make([]BigStruct, 1_000_000)
 | 
			
		||||
	for i := range data {
 | 
			
		||||
		data[i] = BigStruct{float64(i), float64(i), float64(i), float64(i),
 | 
			
		||||
			float64(i), float64(i), float64(i), float64(i), float64(i), float64(i)}
 | 
			
		||||
	}
 | 
			
		||||
	ptrs := ToPtrsStruct(data)
 | 
			
		||||
	b.ResetTimer()
 | 
			
		||||
	for i := 0; i < b.N; i++ {
 | 
			
		||||
		_ = DerefSliceStructUnsafe(ptrs)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user