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

devtools/2024/11/18 11:13: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/devtools/134942.html

相关文章

开源物业管理系统助力智能社区提升服务效率与用户体验

内容概要 开源物业管理系统是一种灵活、智能的解决方案&#xff0c;专为社区物业管理而生。随着智能社区的发展&#xff0c;这种系统变得越来越重要。它不仅帮助物业管理者高效地处理日常事务&#xff0c;还提升了居民的生活体验。在这个日新月异的时代&#xff0c;开源物业管…

AB矩阵秩1乘法,列乘以行

1. AB矩阵相乘 2. 代码测试 python 代码 #!/usr/bin/env python # -*- coding:utf-8 -*- # FileName :ABTest.py # Time :2024/11/17 8:37 # Author :Jason Zhang import numpy as np from abc import ABCMeta, abstractmethodnp.set_printoptions(suppressTrue, pr…

A3超级计算机虚拟机,为大型语言模型LLM和AIGC提供强大算力支持

热门大语言模型项目地址&#xff1a;www.suanjiayun.com/mirrorDetails?id66ac7d478099315577961758 近几个月来&#xff0c;我们目睹了大型语言模型&#xff08;LLMs&#xff09;和生成式人工智能强势闯入我们的视野&#xff0c;显然&#xff0c;这些模型在训练和运行时需要…

YashanDB 23.2.3安装过程,并使用DBeaver进行连接

Yashandb安装 环境准备 虚拟机环境说明 虚拟机系统&#xff1a;centos 7.9&#xff0c;2c&#xff0c;8g&#xff0c;100GB&#xff1b;内存至少4G&#xff0c;否则无法安装&#xff1b; 安装用户&#xff1a;yashan 软件目录&#xff1a;/app/install 安装目录&#xff1a;…

树状数组+概率论,ABC380G - Another Shuffle Window

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 G - Another Shuffle Window 二、解题报告 1、思路分析 不难用树状数组计…

38.判断素数之和 C语言

输入一个数字&#xff0c;判断这个数字可以由哪些素数相加得到 比如24可以是5和19相加得到&#xff0c;而5和19都是素数 这个代码可以找出所有素数组合&#xff0c;如果没有这样的组合输出无 代码比较简单&#xff0c;但是能解决问题&#xff0c;利用了电脑计算速度快的特点…

Scala学习记录,case class,迭代器

case class case class创建的对象的属性是不可改的 创建对象&#xff0c;可以不用写new 自动重写&#xff1a;toString, equals, hashCode, copy 自动重写方法&#xff1a;toString,equals,hashCode,copy 小习一下 1.case class 的定义语法是什么 基本形式&#xff1a;case …

neo4j desktop基本入门

下载安装不在赘述&#xff0c;本文只记述一些neo4j的基本入门操作 连接本地neo4j数据库 1. 点击ADD添加连接 端口一般是7687 账户名和密码忘记了&#xff0c;可以通过neo4j web&#xff08;默认为neo4jneo4j://localhost:7687/neo4j - Neo4j Browser&#xff09;重置密码 AL…