将整数存储为特定数字类型(uint8,int16,uint32,int64等)的内存含义是什么?我知道每种类型都可以采用的整数范围,但是使用适当的类型可以达到一定的内存效率吗?
例如,在Golang中,将某人的年龄存储为uint8而不是单位(根据其规范https://golang.org/ref/spec#Numeric_types相当于uint32或uint64),似乎“更有效”
答案 0 :(得分:5)
固定大小的整数需要精确的内存量。对单个变量使用较小的整数类型“在此处和那里”,您将仅获得少量内存(如果有)。同样,当用作结构字段类型时,由于隐式填充,您可能再也无法获得任何好处。
当您使用固定大小的整数作为(大)切片或数组的元素类型时,内存增益可能会显着且可观。
使用固定大小的整数的另一个(可能更重要)原因可能是要传达您存储在整数中的内容。您也可以使用int32
或int64
类型来存储字节,但是很明显的浪费是,它们不传递存储在其中的数据的有效范围。
另一点是效率。您可以始终使用int64
代替其他有符号整数类型,但是在某些体系结构上对int64
执行操作可能需要多次寄存器操作,因此速度相当慢。同样,rune
类型(int32
的别名)明确表明您打算将其用于unicode代码点。
另一点是一致性。如果使用int32
在一个地方建模,则应坚持使用并在所有地方使用相同的类型。这在Go语言中比在其他语言中更为重要,因为Go的类型系统是严格的(比大多数其他语言都严格),这意味着如果您拥有类型int32
的值,则不能将其分配给{ {1}}类型,反之亦然,而无需显式转换。
int64
与固定大小的整数类型int
和int
不是固定大小,而是根据Spec: Numeric types:
uint
当您使用uint either 32 or 64 bits
int same size as uint
时,针对不同的体系结构,编译器可能会生成更多优化的代码。 通常 int
在面向32位体系结构时为32位,而在面向64位体系结构时为64位。这意味着int
的大小将与目标体系结构的寄存器大小匹配,因此可以通过单个寄存器操作有效地执行整数运算。例如,如果使用int
,则可能需要执行多个(寄存器)运算才能在32位体系结构上执行单个整数运算。
我喜欢认为int64
是一个整数类型,用于以其认为合适的最佳方式描述和传达Go运行时数据结构的某些部分或组件。例如,为数组或切片建立索引或描述其大小,int
是要使用的“自然”类型。
内置函数
int
和len
接受各种类型的参数并返回类型cap
的结果。该实现确保结果始终适合int
。例如,为切片或数组编制索引或描述其长度和容量,int
是建议或强制执行的“自然”类型。
在对数组,切片或int
值使用至少一个迭代变量的for range
语句时,迭代变量(“索引”)的类型为string
。 / p>
还请注意,Rob Pike已为Go 2提出了将int
更改为任意精度的建议。 proposal: spec: change int to be arbitrary precision
答案 1 :(得分:2)
1)固定大小的整数可以用于减少应用程序使用的内存。例如,在3D应用中,使用float32
而不是float64
可能更有意义,因为图形卡仍然需要float32
并使用uint16
而不是{{1 }},例如绘制索引。
也就是说,对于单个变量,只有当您拥有大量值并且可以用精度来换取内存时,它才没有区别。
2)写入磁盘时使用encoding/binary软件包,您将无法使用uint32
或int
,因为它们的大小在操作系统之间会发生变化。您必须使用已知大小的值才能使文件格式明确。
3)与操作系统的API接口时,通常需要使用固定大小的变量。例如,Windows API是32位API,这意味着当您加载Windows DLL时,通常需要对标志等使用32位无符号整数。