AI不可尽信

news2024/11/26 12:15:19

看到某项目有类似这样的一段代码

leaves := make([]int, 10)
leaves = leaves[:0]

没理解这样的连续两行,有何作用? 初始化一个长度和容量都为10的切片,接着把切片长度设置为0

即如下demo: (在线地址)

package main

import "fmt"

func main() {
	leaves := make([]int, 10)
	fmt.Println(leaves)
	leaves = leaves[:0]
	fmt.Println(leaves)

	leaves2 := make([]int, 0, 10)
	fmt.Println(leaves2)
}

输出为:

[0 0 0 0 0 0 0 0 0 0]
[]
[]

为什么不直接leaves := make([]int, 0, 10)? 况且直觉来说,先申请长度为10的,再设置为0, 比直接申请长度为0的,要多一些性能开销吧…

问了下claude.ai

Go语言中leaves := make([]int, 10) leaves = leaves[:0] 和leaves := make([]int, 0, 10) 有何区别?哪种方式更好?

这是一个很好的问题,涉及到 Go 语言中切片的内存分配和使用。让我们详细比较这两种方式:

方式 1:

leaves := make([]int, 10)
leaves = leaves[:0]

方式 2:

leaves := make([]int, 0, 10)

这两种方式的主要区别在于:

  1. 初始化后的状态:

    • 方式 1:初始创建一个长度为 10 的切片,所有元素被初始化为零值(对于 int 类型,就是 0)。然后立即将其长度设置为 0,但保留了容量。
    • 方式 2:创建一个长度为 0,容量为 10 的切片。没有实际的元素被初始化。
  2. 内存分配:

    • 两种方式都会分配能容纳 10 个 int 的底层数组。
  3. 初始化开销:

    • 方式 1:有初始化 10 个元素为零值的开销。
    • 方式 2:没有元素初始化的开销。
  4. 使用方式:

    • 两种方式后续使用 append 的行为是一样的。
  5. 性能:

    • 方式 2 略优于方式 1,因为它避免了不必要的元素初始化。

哪种方式更好?

总的来说,方式 2 leaves := make([]int, 0, 10) 通常被认为是更好的做法,原因如下:

  1. 效率:避免了不必要的元素初始化,特别是当元素类型比 int 更复杂时,这种差异会更明显。

  2. 清晰性:直接表达了"我想要一个空的切片,但预留了 10 个元素的空间"这一意图。

  3. 一致性:与后续使用 append 来添加元素的方式更加一致。

  4. 安全性:避免了可能出现的、使用未被有意义初始化的元素的错误。

示例代码来说明这两种方式的行为:

package main

import "fmt"

func main() {
    // 方式 1
    leaves1 := make([]int, 10)
    fmt.Printf("方式 1 初始: 长度=%d, 容量=%d\n", len(leaves1), cap(leaves1))
    leaves1 = leaves1[:0]
    fmt.Printf("方式 1 重置后: 长度=%d, 容量=%d\n", len(leaves1), cap(leaves1))

    // 方式 2
    leaves2 := make([]int, 0, 10)
    fmt.Printf("方式 2: 长度=%d, 容量=%d\n", len(leaves2), cap(leaves2))

    // 添加元素
    leaves1 = append(leaves1, 1, 2, 3)
    leaves2 = append(leaves2, 1, 2, 3)

    fmt.Printf("方式 1 添加元素后: %v\n", leaves1)
    fmt.Printf("方式 2 添加元素后: %v\n", leaves2)
}

输出将会是:

方式 1 初始: 长度=10, 容量=10
方式 1 重置后: 长度=0, 容量=10
方式 2: 长度=0, 容量=10
方式 1 添加元素后: [1 2 3]
方式 2 添加元素后: [1 2 3]

这个例子展示了两种方式在实际使用中的相似性,但方式 2 避免了初始的元素初始化步骤。

因此,在大多数情况下,leaves := make([]int, 0, 10) 是更好的选择。



看着Claude.ai的回答,“第一种方式有内存分配”, 于是信心满满提了个pr,结果维护这个项目的丹麦老哥回复:

It literally does the same - it doesn't save any "memory overhead". Sorry. This is too pointless of a change to take.



决定做个性能测试加以佐证。

package main

import (
	"testing"
)

func BenchmarkMakeWithLength(b *testing.B) {
	for i := 0; i < b.N; i++ {
		leaves := make([]int, 10)
		leaves = leaves[:0]
	}
}

func BenchmarkMakeWithCapacity(b *testing.B) {
	for i := 0; i < b.N; i++ {
		leaves := make([]int, 0, 10)
		_ = leaves
	}
}

尴尬的是,测试结果,却恰恰并不支持Ai给的这个结论。。


写demo然后查看两者相对应的汇编,好吧,其实两种写法汇编代码是完全一样的。唯一差异也就在于个人习惯和可读性了


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2187487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2023工业3D异常检测文献】CPMF: 基于手工制作PCD描述符和深度学习IAD结合的AD方法

Complementary Pseudo Multimodal Feature for Point Cloud Anomaly Detection 1、Background 早期的点云异常检测(PCD)表示是手工制作的&#xff0c;依赖于启发式设计。随着深度学习的发展&#xff0c;最近的方法采用了基于学习的PCD特征。尽管与基线相比有相当大的改进&…

欧几里得算法--(密码学基础)

根基&#xff1a;gcd(a,b)gcd(b,a mod b) 先举个例子吧&#xff0c;gcd(16,6)gcd(6,4)gcd(4,2)gcd(2,0)2 学习这个定理的时候我想了几个问题. 第一个问题&#xff1a;为什么求出的就一定是他们两个数的公约数&#xff1f; 这个问题很简单我们只需要通过几何来计较即可&#x…

MyBatis——ORM

MyBatis——ORM 验证映射配置ResultType本质是ResultMap具体的转换逻辑 概括的说&#xff0c;MyBatis中&#xff0c;对于映射关系的声明是由开发者在xml文件手动完成的。比如对查询方法而言&#xff0c;你需要显式声明ResultType或ResultMap&#xff0c;这里其实就是在定义数据…

Java JUC(三) AQS与同步工具详解

Java JUC&#xff08;三&#xff09; AQS与同步工具详解 一. ReentrantLock 概述 ReentrantLock 是 java.util.concurrent.locks 包下的一个同步工具类&#xff0c;它实现了 Lock 接口&#xff0c;提供了一种相比synchronized关键字更灵活的锁机制。ReentrantLock 是一种独占…

【Kubernetes】常见面试题汇总(五十三)

目录 118. pod 状态为 ErrlmagePull &#xff1f; 119.探测存活 pod 状态为 CrashLoopBackOff &#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二&#xff09;” 。…

uniapp使用字体图标 ttf svg作为选项图标,还支持变色变图按

在staic目录下有一些ttf文件&#xff0c;如uni.ttf&#xff0c;iconfont.ttf 这些文件中保存这字体svg的源码们&#xff0c;我们也可以在网上找其他的。这些就是我们要显示的突图标的 显示来源。这样不用使用png图标&#xff0c;选中不选中还得用两个图片 我的具体使用如下 &q…

Python入门--循环语句

目录 1. while循环基础语法 2. while循环的嵌套 3. while实现九九乘法表 4. for循环基础语法 5. for循环的嵌套 6. for循环实现九九乘法表 7. 循环中断&#xff1a;break和continue 循环普遍存在于日常生活中&#xff0c;同样&#xff0c;在程序中&#xff0c;循环功能也…

thinkphp6入门(25)-- 分组查询 GROUP_CONCAT

假设表名为 user_courses&#xff0c;字段为 user_id 和 course_name&#xff0c;存储每个用户选修的课程&#xff0c;想查询每个学生选修的所有课程 SQL 原生查询 SELECT user_id, GROUP_CONCAT(course_name) as courses FROM user_courses GROUP BY user_id; ThinkPHP 代码…

python常用库总结(argparse、re、matlpotlab.plot)

文章目录 1.argparse库字符串&#xff08;str&#xff09;布尔值&#xff08;bool&#xff09;选择&#xff08;choices&#xff09;计数&#xff08;count&#xff09;常量&#xff08;store_const 和 store_true&#xff09;多个值&#xff08;nargs&#xff09;可选参数&…

用Python实现运筹学——Day 9: 线性规划的灵敏度分析

一、学习内容 1. 灵敏度分析的定义与作用 灵敏度分析&#xff08;Sensitivity Analysis&#xff09; 是在优化问题中&#xff0c;分析模型参数变化对最优解及目标函数值的影响。它帮助我们了解在线性规划模型中&#xff0c;当某些参数&#xff08;如资源供应量、成本系数等&a…

SQLServer CXPACKET等待事件

文章目录 SQL Server 中的 CXPACKET 等待类型是最容易被误解的等待统计之一。CXPACKET 这个术语来源于 “Class Exchange Packet”&#xff08;类交换包&#xff09;。其本质可以描述为在单个进程的两个并行线程之间交换数据行的过程。其中一个线程是“生产者线程”&#xff0c…

理解Matplotlib构图组成

介绍 Matplotlib 是 Python 中最流行的数据可视化库之一。它提供了一系列丰富的工具&#xff0c;可以绘制高度自定义且适用于各种应用场景的图表。无论你是数据科学家、工程师&#xff0c;还是需要处理数据图形表示的任何人&#xff0c;理解如何操作和定制 Matplotlib 中的图表…

ElasticSearch 备考 -- 备份和恢复

一、题目 备份集群下的索引 task&#xff0c;存储快照名称为 snapshot_1 二、思考 这个涉及的是集群的备份&#xff0c;主要是通过创建快照&#xff0c;涉及到以下2步骤 Setp1&#xff1a;注册一个备份 snapshot repository Setp2&#xff1a;创建 snapshot 可以通过两种方…

Ubuntu18.04安装cuda11.1(出现c++版本问题)

一、概述 需要使用到ubuntu18.04进行cuda的配置&#xff0c;最新版本的cuda跟pytorch的版本不太适配&#xff0c;所以为了能够复现&#xff0c;我选择了一些老版本的cuda11&#xff0c;其使用的范围更加广泛。将自己 二、具体操作 &#xff08;一&#xff09;安装流程 1.官网…

为什么疾风气象大模型比传统天气预报更准?

近年来&#xff0c;气象大模型逐渐成为天气预报的核心工具&#xff0c;其预测精度和可靠性远超传统天气预报方法。本文将探讨气象大模型为何比传统天气预报更加准确的原因&#xff0c;分析其优势以及在气象预测领域的应用前景。 1. 传统天气预报的局限性 传统天气预报通常依赖…

win11/win10/windows下快安装并使用git

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Git 的特点&#xff1f;二、GIT安装方法1.打开GIT官网2.下载git安装程序整个安装过程基本上直接用默认选项就可以 总结 前言 提示&#xff1a;GIT介绍 GI…

十一不停歇-学习ROS2第一天 (10.2 10:45)

话题通信 1.1 发布第一个节点&#xff1a; import rclpy #导入此类模块 rcl类型 from rclpy.node import Node #从这个子模块中导入这类函数 def main(): #定义这个函数 rclpy.init() #使用初始化函数 node Node(hello_python) 将类函数里面的内容调给…

Pikachu- SQL Inject - http header 头注入

header 头注入&#xff0c;是一种场景&#xff1b;跟以往的没区别&#xff0c;只是发生在 header 响应头&#xff1b; 有些时候&#xff0c;后台开发人员为了验证客户端头信息(比如常用的cookie验证)&#xff0c;或者通过http header头信息获取客户端的一些信息&#xff0c;比…

帝国CMS系统开启https后,无法登陆后台的原因和解决方法

今天本地配置好了帝国CMS7.5&#xff0c;传去服务器后&#xff0c;使用http访问一切正常。但是当开启了https&#xff08;SSL&#xff09;后&#xff0c;后台竟然无法登陆进去了。 输入账号密码后&#xff0c;点击登陆&#xff0c;跳转到/e/admin/ecmsadmin.php就变成页面一片…

【Kubernetes】常见面试题汇总(五十四)

目录 120.创建 init C 容器后&#xff0c;其状态不正常&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二&#xff09;” 。 题目 69-113 属于【Kubernetes】的生产…