Go案例优化 | 青训营

78 阅读3分钟

开头

一切为了优化而优化都是耍流氓,肯定是在正确的基础上进行优化。

go 切片的优化

Go 语言切片是对数组的抽象。 Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。 内存分配和释放是非常耗时的操作,因此频繁地对切片进行重新分配和释放会影响程序的性能和效率。当程序中的数据量增加时,内存分配和释放的开销也会增加,这会导致程序变得更加缓慢。

因此,在使用切片时,需要注意内存使用的优化,尽可能地避免频繁地进行内存分配和释放操作。优化内存使用可以减少程序的运行时间和内存占用,提高程序的性能和效率。

切片优化内存的技巧

  1. 预分配切片的容量 在创建切片时,如果能够预先知道其容量,最好设置好预期的容量。这样可以避免内存重新分配的开销。
  2. 重用底层数组 尽可能地重用底层数组可以减少内存分配和释放的开销。可以使用切片的切片操作和 copy 函数来复制数据,避免创建新的切片。
  3. 使用 append 函数时预分配容量 如果在使用 append 函数时预先分配足够的容量,可以避免内存重新分配的开销。尽可能地避免在循环中多次使用 append 函数,这将导致多次内存重新分配。

代码实践

package main

import (
	"fmt"
)

func main() {
	var s1 []int
	var s2 []int

	for i := 0; i < 10000000; i++ {
		s1 = append(s1, i)
		s2 = append(s2, i*2)
	}

	fmt.Printf("s1: %d, s2: %d\n", len(s1), len(s2))

	s3 := s1[:0]
	s4 := s2[:0]
	// var s3 []int
	// var s4 []int
	for i := 0; i < 10000000; i++ {
		s3 = append(s3, i)
		s4 = append(s4, i*2)
	}

	fmt.Printf("s1: %d, s2: %d\n", len(s3), len(s4))

}

开始s3,s4用var创造和用底层数组直接赋值,后者是要快一些。

3的代码实践

package main

import (
	"fmt"
	"math/rand"
	"time"
)

const (
	n = 1000000
)

func main() {
	// 预分配切片的容量
	//data := make([]int, 0, n)
	var data []int
	// 向切片中添加元素并处理
	rand.Seed(time.Now().UnixNano())
	for i := 0; i < n; i++ {
		data = append(data, rand.Intn(1000))
		//fmt.Println(rand.Intn(1000))
	}
	for i := range data {
		//data[i] = process(data[i])
		fmt.Println(data[i])
		if i == 15 {
			break
		}
	}

	fmt.Println("All elements are processed!")
}

这两个的差别不大,make确定了长度,下面直接定义。可能这做错了。

总结

反正切片优化就是少定义,少开空间降低内存。还是要先写出正确的代码。大佬全都写出来了 [借鉴大佬的文章](不背锅运维:Go语言切片内存优化技巧和实战案例_golang 内存优化_不背锅运维的博客-CSDN博客)