Исходники и презентации
This commit is contained in:
22
lessons/slices_and_arrays/access_by_index/main.go
Normal file
22
lessons/slices_and_arrays/access_by_index/main.go
Normal 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)
|
||||
}
|
||||
39
lessons/slices_and_arrays/append_implementation/main.go
Normal file
39
lessons/slices_and_arrays/append_implementation/main.go
Normal 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))
|
||||
}
|
||||
23
lessons/slices_and_arrays/array_moving/main.go
Normal file
23
lessons/slices_and_arrays/array_moving/main.go
Normal 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)
|
||||
}
|
||||
86
lessons/slices_and_arrays/array_operations/main.go
Normal file
86
lessons/slices_and_arrays/array_operations/main.go
Normal 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
|
||||
}
|
||||
11
lessons/slices_and_arrays/arrays_allocation_1/main.go
Normal file
11
lessons/slices_and_arrays/arrays_allocation_1/main.go
Normal 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
|
||||
}
|
||||
11
lessons/slices_and_arrays/arrays_allocation_2/main.go
Normal file
11
lessons/slices_and_arrays/arrays_allocation_2/main.go
Normal file
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
//go:noinline
|
||||
func allocation() *[10]int {
|
||||
var data [10]int
|
||||
return &data
|
||||
}
|
||||
|
||||
func main() {
|
||||
_ = allocation()
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
data1 := [3]int{1, 2, 3}
|
||||
data2 := [2]int{1, 2}
|
||||
data1 = data2 // compliation error
|
||||
}
|
||||
30
lessons/slices_and_arrays/bce_absence/main.go
Normal file
30
lessons/slices_and_arrays/bce_absence/main.go
Normal 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() {}
|
||||
35
lessons/slices_and_arrays/bce_optimization_1/bench_test.go
Normal file
35
lessons/slices_and_arrays/bce_optimization_1/bench_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
34
lessons/slices_and_arrays/bce_optimization_2/bench_test.go
Normal file
34
lessons/slices_and_arrays/bce_optimization_2/bench_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
27
lessons/slices_and_arrays/bce_optimization_3/main.go
Normal file
27
lessons/slices_and_arrays/bce_optimization_3/main.go
Normal 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() {
|
||||
|
||||
}
|
||||
21
lessons/slices_and_arrays/bce_presence/main.go
Normal file
21
lessons/slices_and_arrays/bce_presence/main.go
Normal 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() {}
|
||||
38
lessons/slices_and_arrays/big_slice_correct/main.go
Normal file
38
lessons/slices_and_arrays/big_slice_correct/main.go
Normal 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)
|
||||
}
|
||||
36
lessons/slices_and_arrays/big_slice_incorrect/main.go
Normal file
36
lessons/slices_and_arrays/big_slice_incorrect/main.go
Normal 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)
|
||||
}
|
||||
20
lessons/slices_and_arrays/check_length/main.go
Normal file
20
lessons/slices_and_arrays/check_length/main.go
Normal 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
|
||||
}
|
||||
33
lessons/slices_and_arrays/clip/main.go
Normal file
33
lessons/slices_and_arrays/clip/main.go
Normal 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)
|
||||
}
|
||||
22
lessons/slices_and_arrays/collection_optimization/main.go
Normal file
22
lessons/slices_and_arrays/collection_optimization/main.go
Normal 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))
|
||||
}
|
||||
19
lessons/slices_and_arrays/copy_implementation/main.go
Normal file
19
lessons/slices_and_arrays/copy_implementation/main.go
Normal 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)
|
||||
}
|
||||
10
lessons/slices_and_arrays/copy_slice/main.go
Normal file
10
lessons/slices_and_arrays/copy_slice/main.go
Normal 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)
|
||||
}
|
||||
20
lessons/slices_and_arrays/dangerous_append/main.go
Normal file
20
lessons/slices_and_arrays/dangerous_append/main.go
Normal 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)
|
||||
*/
|
||||
}
|
||||
18
lessons/slices_and_arrays/different_range_by_array/main.go
Normal file
18
lessons/slices_and_arrays/different_range_by_array/main.go
Normal 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)
|
||||
}
|
||||
}
|
||||
31
lessons/slices_and_arrays/dirty_slice/creation_test.go
Normal file
31
lessons/slices_and_arrays/dirty_slice/creation_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
27
lessons/slices_and_arrays/empty_and_nil_slices/main.go
Normal file
27
lessons/slices_and_arrays/empty_and_nil_slices/main.go
Normal 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))
|
||||
}
|
||||
19
lessons/slices_and_arrays/endless_range/main.go
Normal file
19
lessons/slices_and_arrays/endless_range/main.go
Normal 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")
|
||||
}
|
||||
*/
|
||||
}
|
||||
18
lessons/slices_and_arrays/incorrect_range_by_array/main.go
Normal file
18
lessons/slices_and_arrays/incorrect_range_by_array/main.go
Normal 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)
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
25
lessons/slices_and_arrays/memclr/clear_test.go
Normal file
25
lessons/slices_and_arrays/memclr/clear_test.go
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
34
lessons/slices_and_arrays/pointer_to_slice_element/main.go
Normal file
34
lessons/slices_and_arrays/pointer_to_slice_element/main.go
Normal 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)
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
12
lessons/slices_and_arrays/range_task/main.go
Normal file
12
lessons/slices_and_arrays/range_task/main.go
Normal 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"
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
25
lessons/slices_and_arrays/reservation/reservation_test.go
Normal file
25
lessons/slices_and_arrays/reservation/reservation_test.go
Normal 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])
|
||||
}
|
||||
}
|
||||
}
|
||||
13
lessons/slices_and_arrays/resize_slice/main.go
Normal file
13
lessons/slices_and_arrays/resize_slice/main.go
Normal 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])
|
||||
}
|
||||
25
lessons/slices_and_arrays/slice_clearing/main.go
Normal file
25
lessons/slices_and_arrays/slice_clearing/main.go
Normal 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))
|
||||
}
|
||||
12
lessons/slices_and_arrays/slice_increasing/main.go
Normal file
12
lessons/slices_and_arrays/slice_increasing/main.go
Normal 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)
|
||||
}
|
||||
39
lessons/slices_and_arrays/slice_of_slices/main.go
Normal file
39
lessons/slices_and_arrays/slice_of_slices/main.go
Normal 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)
|
||||
}
|
||||
58
lessons/slices_and_arrays/slice_operations/main.go
Normal file
58
lessons/slices_and_arrays/slice_operations/main.go
Normal 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
|
||||
}
|
||||
31
lessons/slices_and_arrays/slice_type_transformation/main.go
Normal file
31
lessons/slices_and_arrays/slice_type_transformation/main.go
Normal 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
|
||||
}
|
||||
22
lessons/slices_and_arrays/slice_with_function_1/main.go
Normal file
22
lessons/slices_and_arrays/slice_with_function_1/main.go
Normal 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))
|
||||
}
|
||||
16
lessons/slices_and_arrays/slice_with_function_2/main.go
Normal file
16
lessons/slices_and_arrays/slice_with_function_2/main.go
Normal 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)
|
||||
}
|
||||
19
lessons/slices_and_arrays/slices_allocation/main.go
Normal file
19
lessons/slices_and_arrays/slices_allocation/main.go
Normal 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
|
||||
}
|
||||
15
lessons/slices_and_arrays/slices_comparison/main.go
Normal file
15
lessons/slices_and_arrays/slices_comparison/main.go
Normal 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))
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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))
|
||||
}
|
||||
15
lessons/slices_and_arrays/slices_to_array_pointer/main.go
Normal file
15
lessons/slices_and_arrays/slices_to_array_pointer/main.go
Normal 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))
|
||||
}
|
||||
15
lessons/slices_and_arrays/slices_to_arrays/main.go
Normal file
15
lessons/slices_and_arrays/slices_to_arrays/main.go
Normal 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))
|
||||
}
|
||||
52
lessons/slices_and_arrays/slicing_operations/main.go
Normal file
52
lessons/slices_and_arrays/slicing_operations/main.go
Normal 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)
|
||||
}
|
||||
15
lessons/slices_and_arrays/slicing_task/main.go
Normal file
15
lessons/slices_and_arrays/slicing_task/main.go
Normal 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)
|
||||
}
|
||||
45
lessons/slices_and_arrays/without_bound_checks/bench_test.go
Normal file
45
lessons/slices_and_arrays/without_bound_checks/bench_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user