Go 语言切片初始化与性能优化:使用 cap 参数的重要性

news/2024/11/18 6:48:55/

在 Go 语言中,切片是一种非常灵活且常用的数据结构,它提供了一种动态数组的抽象。在使用切片时,我们通常会使用 append 函数来添加元素。然而,很少有人意识到在初始化切片时指定其容量(capacity)可以显著提高性能。本文将通过一个基准测试(benchmark)的例子来探讨如何通过使用 cap 参数来优化切片的性能,并详细介绍如何进行基准测试。

切片初始化与 append

在 Go 中,切片的初始化通常使用 make 函数。如果我们不指定容量,make 将分配一个足够容纳初始元素数量的数组,并设置容量与长度相同。当我们使用 append 向切片中添加元素时,如果当前容量不足以容纳新元素,Go 运行时会自动扩容,通常是将容量加倍。

基准测试对比

为了展示使用 cap 参数的重要性,我们设计了两个基准测试:

  1. 不带 cap 参数的初始化BenchmarkSliceInitWithoutCap
  2. cap 参数的初始化BenchmarkSliceInitWithCap

这两个基准测试都执行了相同的操作:向切片中追加 sliceSize(10000)个元素。唯一的区别在于初始化切片时是否指定了容量。

以下是基准测试的代码:

package mainimport "testing"const sliceSize = 10000func BenchmarkSliceInitWithoutCap(b *testing.B) {for n := 0; n < b.N; n++ {sl := make([]int, 0)for i := 0; i < sliceSize; i++ {sl = append(sl, i)}}
}func BenchmarkSliceInitWithCap(b *testing.B) {for n := 0; n < b.N; n++ {sl := make([]int, 0, sliceSize)for i := 0; i < sliceSize; i++ {sl = append(sl, i)}}
}

如何进行基准测试

基准测试是测量代码性能的一种方法,Go 语言提供了一个强大的标准库来帮助开发者执行这些测试。以下是如何进行基准测试的步骤:

  1. 编写基准测试代码:基准测试函数以 Benchmark 开头,并且带有一个 *testing.B 类型的参数。基准测试代码通常放在以 _test.go 结尾的文件中。

  2. 运行基准测试:使用 go test 命令并加上 -bench 标志来运行基准测试。例如,要运行所有的基准测试,可以使用 go test -bench=. 命令。

  3. 解读基准测试结果:执行基准测试后,我们会得到包含性能指标的输出,如每次操作的平均耗时、内存分配次数等。

  4. 使用 benchstat 工具benchstat 是一个用于比较基准测试结果的工具,可以帮助分析性能变化。

基准测试结果

根据基准测试的结果,我们可以看到:

  • 不带 cap 参数的切片:平均每次操作需要 87,552ns。
  • cap 参数的切片:平均每次操作需要 29,880ns。

使用带 cap 参数创建的切片进行 append 操作的平均性能是不带 cap 参数的切片的大约 3 倍左右。

结论

通过这个基准测试,我们可以看到在初始化切片时使用 cap 参数的重要性。这不仅提高了性能,还减少了内存分配的次数,使得代码更加高效。因此,在已知切片所需容量的情况下,我们应该总是指定容量来优化性能。这种优化技巧在处理大量数据或在性能敏感的应用中尤为重要。同时,掌握如何进行基准测试是提高 Go 语言编程性能的关键步骤之一。


测试环境信息

  • API 服务器监听地址:127.0.0.1:56438
  • 操作系统:Windows
  • 架构:amd64
  • 包名:demo
  • CPU:AMD Ryzen 7 4800H with Radeon Graphics

http://www.ppmy.cn/news/1547927.html

相关文章

实习冲刺Day23

算法题 多数元素 169. 多数元素 - 力扣&#xff08;LeetCode&#xff09; 题目要求空间位O(1),时间为O&#xff08;n&#xff09;的方法 采用摩尔投票法解决&#xff0c;摩尔投票法是一种用于在数组中寻找多数元素的有效方法。所谓多数元素&#xff0c;是指在数组中出现次数…

STM32单片机设计防儿童人员误锁/滞留车内警报系统

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 近年来在车辆逐渐普及的情况下&#xff0c;由于家长的疏忽&#xff0c;将…

嵌入式学习-C嘎嘎-Day03

嵌入式学习-C嘎嘎-Day03 1. 友元 friend 1.1 概念 1.2 友元函数 1.3 友元类 1.4 友元成员函数 2. 运算符重载 2.1 概念 2.2 友元函数运算符重载 2.3 成员函数运算符重载 2.4 特殊运算符重载 2.4.1 赋值运算符重载 2.4.2 类型转换运算符重载 2.5 注意事项 3. 字符串类型 string …

比特币前景再度不明,剧烈波动性恐即将回归

比特币市场降温&#xff0c;波动性增加 自特朗普赢得美国总统大选以来&#xff0c;比特币市场的投机狂热有所降温&#xff0c;现货和衍生品市场的活跃度开始减弱。比特币在上周五跌破87000美元&#xff0c;较之前创下的历史高点低了约6500美元。这一变化受到美联储主席鲍威尔讲…

【Mysql 底层原理】MySQL 查询优化器的工作原理:如何生成最优执行计划

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

Elasticsearch面试内容整理-Elasticsearch 基础概念

Elasticsearch 是一个基于 Apache Lucene 的开源分布式搜索和分析引擎,提供强大的全文本搜索、实时数据分析、分布式存储等功能。以下是 Elasticsearch 的一些基础概念: 什么是 Elasticsearch? ● Elasticsearch 是一个用于全文搜索和实时分析的分布式搜索引擎。 ● 开源和可…

el-cascader 使用笔记

1.效果 2.官网 https://element.eleme.cn/#/zh-CN/component/cascader 3.动态加载&#xff08;官网&#xff09; <el-cascader :props"props"></el-cascader><script>let id 0;export default {data() {return {props: {lazy: true,lazyLoad (…

跟李笑来学美式俚语(Most Common American Idioms): Part 10

Most Common American Idioms: Part 10 前言 本文是学习李笑来的Most Common American Idioms这本书的学习笔记&#xff0c;自用。 Github仓库链接&#xff1a;https://github.com/xiaolai/most-common-american-idioms 使用方法: 直接下载下来&#xff08;或者clone到本地…