Go 语言中的通用类型(int / uint)相对于特定类型(int64 / uint64)有啥优势?

Posted

技术标签:

【中文标题】Go 语言中的通用类型(int / uint)相对于特定类型(int64 / uint64)有啥优势?【英文标题】:What are the advantages of the general types (int / uint) over specific types (int64 / uint64) in Go lang?Go 语言中的通用类型(int / uint)相对于特定类型(int64 / uint64)有什么优势? 【发布时间】:2013-05-01 21:37:09 【问题描述】:

我了解 intuint 是 64 位有符号/无符号整数 - 就像 int64 / uint64。而且我也明白int 不仅仅是int64 的别名(就像byte -> uint8 是),所以int64 需要转换为int,反之亦然。但是,使用其中一个有什么好处呢?使用通用类型是否有任何运行时性能损失?

抱歉,如果这是一个常见问题 - 我曾在 Google 上搜索过答案(并在此处搜索过),因为我曾认为其他人之前可能已经出现过,但没有找到任何人就他们如何回答这个问题影响性能(如果有的话)、内存使用(我猜不是它们都是 64 位整数?)以及编译器如何处理它们。

编辑:我知道 int / unit 在 32 位架构上是 32 位。为简洁起见,我假设这是一个 64 位 Golang 环境。

【问题讨论】:

性能和内存使用不是见仁见智的问题。 这个问题有一个足够精确的答案,而不仅仅是基于意见。请投票重新提出问题。 【参考方案1】:

intuint 在 64 位架构上仅是 64 位。在 32 位架构上,它们是 32 位。

一般的答案是,除非您需要一定的精度,否则坚持使用与当前架构上的字大小相同的数据类型(例如 32 位架构上的 32 位)通常会稍微高效一些。

【讨论】:

"slightly" 是夸张的反义词。在 32 位机器上使用 64 位类型通常会导致操作花费至少两倍于 32 位对应物的时间,通常更多是因为增加了寄存器压力。 我知道 int 在 32 位系统上是 32 位(对不起,我应该在我的原始帖子中明确说明。对此感到抱歉)。那么在 64 位系统上处理 int 和 int64 的方式没有区别? @LaurenceMorgan:编译代码后,uintuint64 之间没有区别(假设是 64 位架构)。两者之间的转换是免费的。只有语言有区别。【参考方案2】:

除了 int 是“本机”大小的切片和数组索引之外,还有 int 而不是 int64 或 int32。

【讨论】:

【参考方案3】:

intuint 对应于 Go 实现和运行时中基本 Go 数据结构的最大可能长度。 stringmap[K]T[]Tchan T 的长度总是适合int,而[]Tchan T 的容量总是适合int

通过make 进行的分配必然会返回一个长度和容量始终适合int 的对象。内置函数append 返回一个长度和容量永远不会超过int 的切片。插入新键值对后映射的长度(已定义键的数量)始终适合 int

主要的好处是 intuint最小的(就位大小而言)数据类型,可以安全地在 Go 程序中与普通 Go 结合使用切片和地图等数据类型。

int 的大小与指针 *T 的大小无关。 *T对应的整数类型为uintptr。从理论上讲,Go 实现可以选择将 int 映射到 int16 - 许多 Go 程序仍然可以正常工作,但是将分配的大小限制为 15 位可能过于严格并且会导致运行时恐慌。

在 64 位架构上,Go 1.0 的 intuint 长度为 32 位,Go 1.1 的长度为 64 位(参见 Go 1.1 Release Notes)。此更改将增加某些 Go 程序在 64 位架构上的内存使用量。.

在 Go 程序中显式使用 int64 而不是 int 会使其在 Go 1.0 和 32 位架构下变慢,因为:

intint64 之间的转化次数

某些 CPU 指令(例如除法)的性能取决于操作数的大小

在 Go 程序中显式使用 int64 而不是 int 可以使其在 64 位架构的 Go 1.0 下更快,因为:

如果所有操作数都是 64 位,编译器可以为地址和偏移量计算生成更高效的代码。在计算地址和偏移量较慢时混合 32 位和 64 位操作数。

在访问[1<<16]T 时使用uint16 作为索引允许编译器删除边界检查指令。

【讨论】:

我已经很轻松地将uint16 用于地图和切片,因此声明intuint最小 整数类型,可以安全地与地图和切片一起使用slices 不仅是错误的,而且可能与事实相反。

以上是关于Go 语言中的通用类型(int / uint)相对于特定类型(int64 / uint64)有啥优势?的主要内容,如果未能解决你的问题,请参考以下文章

Go语言基础之基本数据类型

2Go语言基础之数据类型

2Go语言基础之数据类型

Go基本数据类型

Go语言中基本数据类型初识

go语言-数据类型及类型之间转换