Исходники и презентации

This commit is contained in:
2025-05-23 07:26:39 +03:00
parent aa948179d5
commit 02d8430a3a
514 changed files with 13773 additions and 0 deletions

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"unsafe"
)
func main() {
const elemSize = unsafe.Sizeof(int32(0)) // 4 bytes
array := [...]int32{1, 2, 3}
pointer := unsafe.Pointer(&array)
first := *(*int32)(unsafe.Add(pointer, 0*elemSize)) // => data2[0]
second := *(*int32)(unsafe.Add(pointer, 1*elemSize)) // => data2[1]
third := *(*int32)(unsafe.Add(pointer, 2*elemSize)) // => data2[2]
dangerous1 := *(*int32)(unsafe.Add(pointer, -1)) // => data2[-1]
dangerous2 := *(*int32)(unsafe.Add(pointer, 3)) // => data2[3]
fmt.Println("correct:", first, second, third)
fmt.Println("dangeroues:", dangerous1, dangerous2)
}

View File

@ -0,0 +1,39 @@
package main
import "fmt"
func Append(slice []int, data ...int) []int {
previousLength := len(slice)
newLength := previousLength + len(data)
if newLength > cap(slice) {
// without smart growth for big slices
capacity := previousLength * 2
if capacity == 0 {
capacity = 1
}
newSlice := make([]int, capacity)
copy(newSlice, slice)
slice = newSlice
}
slice = slice[:newLength]
copy(slice[previousLength:newLength], data)
return slice
}
func main() {
data := []int{}
data = append(data, 1)
data = append(data, 2)
data = append(data, 3)
data = append(data, 4)
data = append(data, 5)
data = append(data, 6)
data = append(data, 7)
data = append(data, 8)
data = append(data, 9)
fmt.Println(data, len(data), cap(data))
}

View File

@ -0,0 +1,23 @@
package main
import (
"fmt"
"unsafe"
)
//go:noinline
func allocation(index int) byte {
var data [1 << 20]byte
return data[index]
}
func main() {
var array [10]int
address := (uintptr)(unsafe.Pointer(&array))
fmt.Println("#1 array address:", address)
allocation(100)
address = (uintptr)(unsafe.Pointer(&array))
fmt.Println("#2 array address:", address)
}

View File

@ -0,0 +1,86 @@
package main
import (
"fmt"
"unsafe"
)
func accessToElement1() {
data := [3]int{1, 2, 3}
idx := 4
fmt.Println(data[idx]) // panic
fmt.Println(data[4]) // compilation error
}
func accessToElement2() {
data := [3]int{1, 2, 3}
idx := -1
fmt.Println(data[idx]) // panic
fmt.Println(data[-1]) // compilation error
}
func arrayLen() {
data := [10]int{}
fmt.Println(len(data)) // 10
}
func capArray() {
var data [10]int
fmt.Println(cap(data)) // 10
}
func arraysComparison() {
first := [...]int{1, 2, 3}
second := [...]int{1, 2, 3}
// except arrays whose element types are incomparable types
fmt.Println(first == second)
fmt.Println(first != second)
// [<, <=, >, >=] -> compilation error
}
func emptyArray() {
var data [10]byte
fmt.Println(unsafe.Sizeof(data)) // 10
//data == nil // compilation error
}
func zeroArray() {
var data [0]int
fmt.Println(unsafe.Sizeof(data)) // 0
}
func arrayOfEmptyStructs() {
var data [10]struct{}
fmt.Println(unsafe.Sizeof(data)) // 0
}
func negativeArray() {
var data [-1]int // compilation error
_ = data
}
func arrayCreation() {
length1 := 100
var data1 [length1]int // compilation error
_ = length1
_ = data1
const length2 = 100
var data2 [length2]int
_ = data2
}
func makeArray() {
_ = make([10]int, 10) // compilation error
}
func appendToArray() {
_ = append([10]int{}, 10) // compilation error
}

View File

@ -0,0 +1,11 @@
package main
// go build -gcflags='-m' . | grep escape
func main() {
var arrayWithStack [10 << 20]int8
_ = arrayWithStack
var arrayWithHeap [10<<20 + 1]int8
_ = arrayWithHeap
}

View File

@ -0,0 +1,11 @@
package main
//go:noinline
func allocation() *[10]int {
var data [10]int
return &data
}
func main() {
_ = allocation()
}

View File

@ -0,0 +1,7 @@
package main
func main() {
data1 := [3]int{1, 2, 3}
data2 := [2]int{1, 2}
data1 = data2 // compliation error
}

View File

@ -0,0 +1,30 @@
package main
// go run -gcflags="-d=ssa/check_bce" main.go
func fn1(data []int, check func(int) bool) []int {
var idx = 0
for _, value := range data {
if check(value) {
data[idx] = value // Found IsInBounds
idx++
}
}
return data[:idx] // Found IsSliceInBounds
}
func fn2(lhs, rhs []byte) {
for idx := range min(len(lhs), len(rhs)) {
_ = lhs[idx] // Found IsInBounds
_ = rhs[idx] // Found IsInBounds
}
}
func fn3(data [256]byte) {
for idx := 0; idx < 128; idx++ {
_ = data[2*idx] // Found IsInBounds
}
}
func main() {}

View File

@ -0,0 +1,35 @@
package main
import "testing"
// go test -gcflags="-d=ssa/check_bce" -bench=. bench_test.go
func sum1(values []int) int {
return values[0] + // Found IsInBounds
values[1] + // Found IsInBounds
values[2] + // Found IsInBounds
values[3] // Found IsInBounds
}
func sum2(values []int) int {
return values[3] + // Found IsInBounds
values[2] +
values[1] +
values[0]
}
var Result int
func BenchmarkSum1(b *testing.B) {
values := []int{1, 2, 3, 4}
for i := 0; i < b.N; i++ {
Result = sum1(values)
}
}
func BenchmarkSum2(b *testing.B) {
values := []int{1, 2, 3, 4}
for i := 0; i < b.N; i++ {
Result = sum2(values)
}
}

View File

@ -0,0 +1,34 @@
package main
import "testing"
// go test -gcflags="-d=ssa/check_bce" -bench=. bench_test.go
func fn1(s []int, i int) {
_ = s[i+3] // Found IsInBounds
_ = s[i+2] // Found IsInBounds
_ = s[i+1] // Found IsInBounds
_ = s[i] // Found IsInBounds
}
func fn2(s []int, i int) {
s = s[i : i+4] // Found IsSliceInBounds
_ = s[3]
_ = s[2]
_ = s[1]
_ = s[0]
}
func BenchmarkFN1(b *testing.B) {
values := []int{1, 2, 3, 4}
for i := 0; i < b.N; i++ {
fn1(values, 0)
}
}
func BenchmarkFN2(b *testing.B) {
values := []int{1, 2, 3, 4}
for i := 0; i < b.N; i++ {
fn2(values, 0)
}
}

View File

@ -0,0 +1,27 @@
package main
// go test -gcflags="-d=ssa/check_bce" -bench=. bench_test.go
func sum1(values []int, size int) int {
sum := 0
for i := 0; i < size; i++ {
sum += values[i]
}
return sum
}
func sum2(values []int, size int) int {
_ = values[size-1] // for BCE
sum := 0
for i := 0; i < size-1; i++ {
sum += values[i]
}
return sum
}
func main() {
}

View File

@ -0,0 +1,21 @@
package main
// go run -gcflags="-d=ssa/check_bce" main.go
func fn1(s []int) {
for i := range s {
_ = s[i]
_ = s[i:]
_ = s[:i+1]
}
}
func fn2(s []int) {
for i := 0; i < len(s); i++ {
_ = s[i]
_ = s[i:]
_ = s[:i+1]
}
}
func main() {}

View File

@ -0,0 +1,38 @@
package main
import (
"fmt"
"runtime"
)
func printAllocs() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d MB\n", m.Alloc/1024/1024)
}
func findSequence(data []byte) []byte {
for i := 0; i < len(data)-1; i++ {
if data[i] == 0x00 && data[i+1] == 0x00 {
partData := make([]byte, 20)
copy(partData, data[i+2:])
return partData
}
}
return nil
}
func main() {
data := make([]byte, 1<<30)
// let's imagine that data was read from a file
sequence := findSequence(data)
_ = sequence // using of sequence later
printAllocs()
runtime.GC()
printAllocs()
runtime.KeepAlive(sequence)
}

View File

@ -0,0 +1,36 @@
package main
import (
"fmt"
"runtime"
)
func printAllocs() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d MB\n", m.Alloc/1024/1024)
}
func findSequence(data []byte) []byte {
for i := 0; i < len(data)-1; i++ {
if data[i] == 0x00 && data[i+1] == 0x00 {
return data[i : i+20]
}
}
return nil
}
func main() {
data := make([]byte, 1<<30)
// let's imagine that data was read from a file
sequence := findSequence(data)
_ = sequence // using of sequence later
printAllocs()
runtime.GC()
printAllocs()
runtime.KeepAlive(sequence)
}

View File

@ -0,0 +1,20 @@
package main
// Need to show solution
func handleOperations(id string) {
operations := getOperations(id)
if operations == nil {
// handling...
}
}
func getOperations(id string) []float32 {
opearations := []float32{}
if id == "" {
return opearations
}
// adding operations...
return opearations
}

View File

@ -0,0 +1,33 @@
package main
import (
"fmt"
"runtime"
"slices"
"unsafe"
)
func printAllocs() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d MB\n", m.Alloc/1024/1024)
}
func main() {
data := make([]int, 10, 100<<20)
fmt.Println("data:", unsafe.SliceData(data), len(data), cap(data))
printAllocs()
temp1 := data[:10]
fmt.Println("temp1:", unsafe.SliceData(temp1), len(temp1), cap(temp1))
temp2 := slices.Clip(data) // data[:10:10]
fmt.Println("temp2:", unsafe.SliceData(temp2), len(temp2), cap(temp2))
runtime.GC()
printAllocs()
runtime.KeepAlive(temp1)
runtime.KeepAlive(temp2)
}

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"runtime"
)
func printAllocs() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d MB\n", m.Alloc/1024/1024)
}
func main() {
data := make([]byte, 1<<31)
printAllocs()
runtime.GC()
printAllocs()
fmt.Println(len(data))
}

View File

@ -0,0 +1,19 @@
package main
import "fmt"
func cp(dst, src []int) {
minLength := min(len(dst), len(src))
for idx := 0; idx < minLength; idx++ {
dst[idx] = src[idx]
}
}
func main() {
src := []int{1, 2, 3, 4, 5}
dst := make([]int, 3)
copy(dst, src)
fmt.Println("src", src)
fmt.Println("dst", dst)
}

View File

@ -0,0 +1,10 @@
package main
import "fmt"
func main() {
src := []int{1, 2, 3}
var dst []int
copy(dst, src)
fmt.Println("copied:", dst)
}

View File

@ -0,0 +1,20 @@
package main
import "fmt"
func main() {
data := make([]int, 4, 5)
copy := append(data, 5)
fmt.Println(data)
//fmt.Println(data[:5])
fmt.Println(copy)
/*
data := make([]int, 5, 5)
copy := append(data, 5)
fmt.Println(data)
fmt.Println(copy)
*/
}

View File

@ -0,0 +1,18 @@
package main
import "fmt"
func main() {
data := [...]int{1, 2, 3}
for value := range data { // copy of array
fmt.Println(value)
}
for value := range &data { // not a copy of array
fmt.Println(value)
}
for value := range data[:] { // not a copy of array
fmt.Println(value)
}
}

View File

@ -0,0 +1,31 @@
package main
import (
"strings"
"testing"
"unsafe"
)
// go test -bench=. creation_test.go
func makeDirty(size int) []byte {
var sb strings.Builder
sb.Grow(size)
pointer := unsafe.StringData(sb.String())
return unsafe.Slice(pointer, size)
}
var Result []byte
func BenchmarkMake(b *testing.B) {
for i := 0; i < b.N; i++ {
Result = make([]byte, 0, 10<<20)
}
}
func BenchmarkMakeDirty(b *testing.B) {
for i := 0; i < b.N; i++ {
Result = makeDirty(10 << 20)
}
}

View File

@ -0,0 +1,27 @@
package main
import (
"fmt"
"unsafe"
)
func main() {
var data []string
fmt.Println("var data []string:")
fmt.Printf("\tempty=%t nil=%t size=%d data=%p\n", len(data) == 0, data == nil, unsafe.Sizeof(data), unsafe.SliceData(data))
data = []string(nil)
fmt.Println("data = []string(nil):")
fmt.Printf("\tempty=%t nil=%t size=%d data=%p\n", len(data) == 0, data == nil, unsafe.Sizeof(data), unsafe.SliceData(data))
data = []string{}
fmt.Println("data = []string{}:")
fmt.Printf("\tempty=%t nil=%t size=%d data=%p\n", len(data) == 0, data == nil, unsafe.Sizeof(data), unsafe.SliceData(data))
data = make([]string, 0)
fmt.Println("data = make([]string, 0):")
fmt.Printf("\tempty=%t nil=%t size=%d data=%p\n", len(data) == 0, data == nil, unsafe.Sizeof(data), unsafe.SliceData(data))
empty := struct{}{}
fmt.Println("empty struct address:", unsafe.Pointer(&empty))
}

View File

@ -0,0 +1,19 @@
package main
import "fmt"
func main() {
data := []int{0, 1, 2}
for range data {
data = append(data, 10)
fmt.Println("iteration")
}
/*
data := []int{0, 1, 2}
for i := 0; i < len(data); i++ {
data = append(data, 10)
fmt.Println("iteration")
}
*/
}

View File

@ -0,0 +1,18 @@
package main
import (
"fmt"
"unsafe"
)
func main() {
values := [...]int{100, 200, 300}
// also actual for slices
for idx, value := range values {
value += 50
fmt.Println("#1:", unsafe.Pointer(&value), "#2:", unsafe.Pointer(&values[idx]))
}
fmt.Println("values:", values)
}

View File

@ -0,0 +1,18 @@
package main
import "fmt"
func main() {
var array *[4]int // = nil
fmt.Println("length =", len(array))
fmt.Println("capacity =", cap(array))
for idx := range array { // ok
fmt.Println(idx)
}
for idx, value := range array { // panic
fmt.Println(idx, value)
}
}

View File

@ -0,0 +1,40 @@
package main
import (
"testing"
)
// go test -bench=. comparison_test.go
const size = 1 << 10
func BenchmarkWithoutOptimizations(b *testing.B) {
data := make([]int, size)
for i := 0; i < b.N; i++ {
for j := 0; j < len(data); j++ {
data[j] = i
}
}
}
func BenchmarkWithCalculatedLength(b *testing.B) {
data := make([]int, size)
for i := 0; i < b.N; i++ {
length := len(data)
for j := 0; j < length; j++ {
data[j] = i
}
}
}
func BenchmarkWithLoopUnwinding(b *testing.B) {
data := make([]int, size)
for i := 0; i < b.N; i++ {
for j := 0; j < len(data)/4; j += 4 {
data[j] = i
data[j+1] = i
data[j+2] = i
data[j+3] = i
}
}
}

View File

@ -0,0 +1,25 @@
package main
import (
"testing"
)
// go test -bench=. clear_test.go
func BenchmarkClearWithFive(b *testing.B) {
data := make([]int, 10*1024)
for i := 0; i < b.N; i++ {
for idx := range data {
data[idx] = 5
}
}
}
func BenchmarkClearWithZero(b *testing.B) {
data := make([]int, 10*1024)
for i := 0; i < b.N; i++ {
for idx := range data {
data[idx] = 0
}
}
}

View File

@ -0,0 +1,34 @@
package main
import (
"fmt"
"runtime"
)
func printAllocs() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d MB\n", m.Alloc/1024/1024)
}
func FindElement(numbers []int, target int) *int {
for idx := range numbers {
if numbers[idx] == target {
return &numbers[idx]
}
}
return nil
}
func main() {
var numbers = make([]int, 1<<30)
pointer := FindElement(numbers, 0)
_ = pointer
printAllocs()
runtime.GC()
printAllocs()
runtime.KeepAlive(pointer)
}

View File

@ -0,0 +1,39 @@
package main
import "testing"
// go test -bench=. comparison_test.go
type account struct {
balance int
}
func BenchmarkWithPointers(b *testing.B) {
accounts := [...]*account{
{balance: 100},
{balance: 200},
{balance: 300},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, a := range accounts {
a.balance += 1
}
}
}
func BenchmarkWithIndices(b *testing.B) {
accounts := [...]account{
{balance: 100},
{balance: 200},
{balance: 300},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for i := range accounts {
accounts[i].balance += 1
}
}
}

View File

@ -0,0 +1,12 @@
package main
func main() {
var x = []string{"A", "M", "C"}
for i, s := range x {
print(i, s, ",")
x[i+1] = "M"
x = append(x, "Z")
x[i+1] = "Z"
}
}

View File

@ -0,0 +1,43 @@
package main
import "testing"
// go test -bench=. -benchmem comparison_test.go
const bufferSize = 10
type ReaderWithSliceArgument struct{}
func (r ReaderWithSliceArgument) Read(p []byte) (int, error) {
for i := 0; i < bufferSize; i++ {
p[i] = byte(i)
}
return bufferSize, nil
}
type ReaderWithSliceReturn struct{}
func (r ReaderWithSliceReturn) Read(n int) ([]byte, error) {
p := make([]byte, n)
for i := 0; i < n; i++ {
p[i] = byte(i)
}
return p, nil
}
func BenchmarkSliceWithArgument(b *testing.B) {
for i := 0; i < b.N; i++ {
p := make([]byte, bufferSize)
reader := ReaderWithSliceArgument{}
_, _ = reader.Read(p)
}
}
func BenchmarkSliceWithReturn(b *testing.B) {
for i := 0; i < b.N; i++ {
reader := ReaderWithSliceReturn{}
_, _ = reader.Read(bufferSize)
}
}

View File

@ -0,0 +1,25 @@
package main
import "testing"
// go test -bench=. -benchmem reservation_test.go
func BenchmarkWithoutReservation(b *testing.B) {
sourseData := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}
for i := 0; i < b.N; i++ {
targetData := make([]int, 0)
for j := 0; j < len(sourseData); j++ {
targetData = append(targetData, sourseData[j])
}
}
}
func BenchmarkWithReservation(b *testing.B) {
sourseData := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}
for i := 0; i < b.N; i++ {
targetData := make([]int, 0, len(sourseData))
for j := 0; j < len(sourseData); j++ {
targetData = append(targetData, sourseData[j])
}
}
}

View File

@ -0,0 +1,13 @@
package main
import "fmt"
func main() {
data := make([]int, 3, 6) // len = 3, cap = 6
// fmt.Println(data[4]) // panic
data = data[:6] // len = 6, cap = 6
fmt.Println(data[4])
}

View File

@ -0,0 +1,25 @@
package main
import "fmt"
func main() {
// remove all elements
first := []int{1, 2, 3, 4, 5}
first = nil
fmt.Println("first: ", first, " : ", len(first), " : ", cap(first))
// keep allocated memory
second := []int{1, 2, 3, 4, 5}
second = second[:0]
fmt.Println("second:", second, " : ", len(second), " : ", cap(second))
// zero out all elements
third := []int{1, 2, 3, 4, 5}
clear(third)
fmt.Println("third: ", third, " : ", len(third), " : ", cap(third))
// zero two elements
fourth := []int{1, 2, 3, 4, 5}
clear(fourth[1:3])
fmt.Println("fourth:", fourth, " : ", len(fourth), " : ", cap(fourth))
}

View File

@ -0,0 +1,12 @@
package main
func main() {
slice := make([]int, 0, 3)
println("slice:", slice, "- slice header address:", &slice)
slice = append(slice, 1, 2, 3)
println("slice full capacity:", slice)
slice = append(slice, 4)
println("slice after exceed capacity:", slice)
}

View File

@ -0,0 +1,39 @@
package main
import (
"fmt"
"runtime"
)
type Data struct {
values []byte
}
func printAllocs() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("%d MB\n", m.Alloc/1024/1024)
}
func GetData() []Data {
data := make([]Data, 1000) // ~24KB
for i := 0; i < len(data); i++ {
data[i] = Data{
values: make([]byte, 1<<20),
}
}
clear(data[2:])
return data[:2]
}
func main() {
data := GetData()
printAllocs()
runtime.GC()
printAllocs()
runtime.KeepAlive(data)
}

View File

@ -0,0 +1,58 @@
package main
import (
"fmt"
)
func accessToElement1() {
data := make([]int, 3)
fmt.Println(data[4]) // panic
}
func accessToElement2() {
data := make([]int, 3, 6)
fmt.Println(data[4]) // panic
}
func accessToElement3() {
data := make([]int, 3, 6)
_ = data[-1] // compilation error
}
func accessToNilSlice1() {
var data []int
_ = data[0] // panic
}
func accessToNilSlice2() {
var data []int
data[0] = 10 // panic
}
func appendToNilSlice() {
var data []int
data = append(data, 10)
}
func rangeByNilSlice() {
var data []int
for range data {
}
}
func makeZeroSlice() {
data := make([]int, 0)
fmt.Println(len(data)) // 0
fmt.Println(cap(data)) // 0
}
func makeSlice() {
_ = make([]int, -5) // compilation error
_ = make([]int, 10, 5) // compilation error
size := -5
_ = make([]int, size) // panic
size = 5
_ = make([]int, size*2, size) // panic
}

View File

@ -0,0 +1,31 @@
package main
import (
"unsafe"
)
type slice struct {
data unsafe.Pointer
len int
cap int
}
func Transform(data []byte) []int {
sliceData := unsafe.Pointer(&data[0])
sizeType := int(unsafe.Sizeof(0))
length := len(data) / sizeType
var result []int
resultPtr := (*slice)(unsafe.Pointer(&result))
resultPtr.data = sliceData
resultPtr.len = length
resultPtr.cap = length
return result
}
func main() {
data := make([]byte, 800)
converted := Transform(data)
_ = converted
}

View File

@ -0,0 +1,22 @@
package main
import "fmt"
func main() {
data := []int{1, 2, 3, 4} // len = 4, cap = 4
fmt.Println("initial slice: ", data)
process1(data)
fmt.Println("after process1:", data)
process2(data)
fmt.Println("after process2:", data)
}
func process1(data []int) {
data[2] = 5
}
func process2(data []int) {
data = append(data, 6)
fmt.Println("len:", len(data), "cap:", cap(data))
}

View File

@ -0,0 +1,16 @@
package main
import "fmt"
func main() {
data := make([]int, 3, 6)
fmt.Println("initial slice:", data)
process(data)
fmt.Println("after process:", data)
fmt.Println("after process:", data[:4])
}
func process(data []int) {
data = append(data, 5)
}

View File

@ -0,0 +1,19 @@
package main
// go build -gcflags='-m' . |& grep escape
func main() {
sliceWithStack := make([]byte, 64<<10)
_ = sliceWithStack
size := 10
sliceWithHeap1 := make([]byte, size)
_ = sliceWithHeap1
sliceWithHeap2 := make([]byte, 64<<10+1)
_ = sliceWithHeap2
// unknown ...
var sliceSpecialCase = []byte{1 << 30: 1}
_ = sliceSpecialCase
}

View File

@ -0,0 +1,15 @@
package main
import (
"fmt"
"reflect"
)
func main() {
data1 := []int{1, 2, 3, 4, 5}
data2 := []int{1, 2, 3, 4, 5}
// data1 == data2 -> compilation error
fmt.Println("equal:", reflect.DeepEqual(data1, data2))
}

View File

@ -0,0 +1,50 @@
package main
import (
"fmt"
"reflect"
"testing"
)
// go test -bench=. -benchmem comparison_test.go
func equal(lhs, rhs []int) bool {
if len(lhs) != len(rhs) {
return false
}
for i := 0; i < len(lhs); i++ {
if lhs[i] != rhs[i] {
return false
}
}
return true
}
func BenchmarkWithEqualFunction(b *testing.B) {
lhs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
rhs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
for i := 0; i < b.N; i++ {
_ = equal(lhs, rhs) // slices.Equal(...)
}
}
func BenchmarkWithReflect(b *testing.B) {
lhs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
rhs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
for i := 0; i < b.N; i++ {
_ = reflect.DeepEqual(lhs, rhs)
}
}
func BenchmarkWithSprint(b *testing.B) {
lhs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
rhs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
for i := 0; i < b.N; i++ {
_ = fmt.Sprint(lhs) == fmt.Sprint(rhs)
}
}

View File

@ -0,0 +1,19 @@
package main
import (
"fmt"
"reflect"
)
type client struct {
identifier string
operations []int
}
func main() {
data1 := make([]client, 10)
data2 := make([]client, 10)
data1[1].operations = append(data1[1].operations, 10)
fmt.Println("equal:", reflect.DeepEqual(data1, data2))
}

View File

@ -0,0 +1,15 @@
package main
import (
"fmt"
)
func main() {
slice := make([]int, 3, 6)
array := (*[3]int)(slice)
slice[0] = 10
fmt.Println("slice = ", slice, len(slice), cap(slice))
fmt.Println("array =", array, len(array), cap(array))
}

View File

@ -0,0 +1,15 @@
package main
import (
"fmt"
)
func main() {
slice := make([]int, 3, 6)
array := [3]int(slice[:3])
slice[0] = 10
fmt.Println("slice =", slice, len(slice), cap(slice))
fmt.Println("array =", array, len(array), cap(array))
}

View File

@ -0,0 +1,52 @@
package main
import (
"fmt"
"slices"
)
func sliceToEnd() {
data := make([]int, 4, 6)
slice := data[2:]
fmt.Println(len(slice)) // 2
fmt.Println(cap(slice)) // 4
}
func sliceMoreThanSize() {
data := make([]int, 2, 6)
slice1 := data[1:6]
_ = slice1
}
func sliceWithIncorrectIndeces() {
data := make([]int, 2, 6)
slice2 := data[1:7] // panic
_ = slice2
slice3 := data[2:1] // compilation error
_ = slice3
left := 2
right := 1
slice4 := data[left:right] // panic
_ = slice4
}
func sliceWithNilSlice() {
var data []int
slice := data[:]
slice = data[0:0]
slice = data[0:1] // panic
_ = slice
}
func increaseCapacity() {
data := make([]int, 0, 10)
data = data[:10:100] // panic
slices.Grow(data, 100)
}

View File

@ -0,0 +1,15 @@
package main
import "fmt"
func main() {
a := [...]int{0, 1, 2, 3}
x := a[:1]
y := a[2:]
x = append(x, y...)
x = append(x, y...)
fmt.Println("a:", a)
fmt.Println("x:", x)
}

View File

@ -0,0 +1,45 @@
package main
import (
"testing"
"unsafe"
)
// go test -gcflags="-d=ssa/check_bce" -bench=. bench_test.go
func sum1(values []int, size int) int {
sum := 0
for i := 0; i < size; i++ {
sum += values[i]
}
return sum
}
func sum2(values []int, size int) int {
sum := 0
startPtr := unsafe.Pointer(&values[0])
for i := 0; i < size-1; i++ {
sum += *(*int)(
unsafe.Pointer(uintptr(startPtr) + uintptr(i)*unsafe.Sizeof(values[0])),
)
}
return sum
}
var Result int
func BenchmarkSum1(b *testing.B) {
values := make([]int, 1<<20)
for i := 0; i < b.N; i++ {
Result = sum1(values, 1<<20)
}
}
func BenchmarkSum2(b *testing.B) {
values := make([]int, 1<<20)
for i := 0; i < b.N; i++ {
Result = sum2(values, 1<<20)
}
}