跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • golang 里面为什么要设计 int 这样一个数据类型?
未分類
14 1 月 2021

golang 里面为什么要设计 int 这样一个数据类型?

golang 里面为什么要设计 int 这样一个数据类型?

資深大佬 : jiangwei2222 10

在 golang 里面,有 int64,int32,int 这 3 种数据类型。

int64: 占 64 位的整数数据类型

int32: 占 32 位的整数数据类型

int: 在 64 位处理器上占 64 位,在 32 位处理器上面占 32 位

于是我就纳闷了,int 这个数据类型不是埋坑吗?不同的处理器上面可能导致不同的运行结果,那设计这个数据类型的意义是啥呢?为啥不只保留 int64 和 int32,由程序员指定长度,保证运行结果的一致性

我 google 查了很久,没找到相关的资料,还望了解的老哥赐教

大佬有話說 (19)

  • 資深大佬 : xuanbg

    因为程序员往往不能预知他写的代码会在什么环境下运行……

  • 資深大佬 : wudicgi

    老哥没见过 C 语言里的 int, int32_t, int64_t ?

  • 主 資深大佬 : jiangwei2222

    @xuanbg #1 就因为不能预知,所有指定使用 int64 或者 int32 不更加保险吗

  • 資深大佬 : no1xsyzy

    有一个可能性是为了效率,在 64 位上为了 int32 需要 runtime 手动限制只使用低 32 位,可能需要手动调整溢出 flag ?
    32 位上 int64 是必然需要模拟的……

  • 資深大佬 : ruyu

    在不 care 最大值的时候使用 int, 让所有的 CPU 都开心.

  • 資深大佬 : no1xsyzy

    如果说你肯定该数远远达不到 int32 和 int64 (比如一个 flag,只能取 012,其他均视为未定义行为),那么这个 overhead 就比较明显了。
    而如果你有一百万个这样的数……

  • 資深大佬 : zoharSoul

    我也挺纳闷的

  • 資深大佬 : icexin

    int 跟机器字长一致,这样可以获取最大的执行效率。在不关心数值范围的场景下 int 足够了,比如数组下标。相反如果你在 32 位机器上使用 int64,本来一条指令的事情要变成多条指令。
    int32 和 int64 这些一般用于编解码、底层硬件相关,或者是数值范围敏感的场景。

  • 資深大佬 : xuanbg

    @jiangwei2222 如果你指定 x64,在 x86 平台上就跑不起来啦。指定 x86,x64 平台倒是能跑,但性能就浪费了。

  • 資深大佬 : eason1874

    我的理解相反,int 是平台原生,int32 int64 才是有意设计的

  • 資深大佬 : LANB0

    在 golang 里面,有 int64,int32,int 这 3 种数据类型。
    int64: 占 64 位的整数数据类型

    int32: 占 32 位的整数数据类型

    int: 在 64 位处理器上占 64 位,在 32 位处理器上面占 32 位

    在 c/c++ 里面,有 long long int,int,long int 这 3 种数据类型。
    long long int: 占 64 位的整数数据类型

    int: 占 32 位的整数数据类型(32 位及 64 位平台,8 位和 16 位不考虑了)

    long int: 在 64 位处理器上占 64 位,在 32 位处理器上面占 32 位

    实际上,在不需要做存储和通讯协议数据对齐的场景下,long int 是在跨平台情况下效率最高的。
    跨平台存储和通讯协议数据对齐场景下,4 字节就固定 int32,8 字节就固定 int64

  • 資深大佬 : teawithlife

    看到 C99/C++11 的这些,你会更纳闷的
    en.cppreference.com/w/c/types/integer
    其实原因很简单,就是为了执行效率,一些情况下,我们并不关心 int 到底是 32 位还是 64 位的,反正都够用,这时候就没必要强制指定位数,而是让编译器自己去自行选择效率最高的位数

  • 資深大佬 : secondwtq

    仅就 x86 而言,int64 还真不一定比 int32 快
    “快不快”不仅仅是指令支持的问题,数据宽了一倍,占用的缓存空间、内存带宽都加了一倍。如果真有一百万个这样的数,可能还真是 32 位好一点,特别再考虑到 SIMD 的情况下

    如果这货的行为真的像主说的一样“在 64 位处理器上占 64 位,在 32 位处理器上面占 32 位”的话,那么看 C/C++ 是正解,不过鉴于大道至简的 Go 目标之一就是干死 C++,估计没人会去看的。

    C 里面有一个类型叫 size_t,相当于 Go 的 uint,还有个 ptrdiff_t,相当于 Go 里的 int (假设主说的行为是对的)
    size_t 顾名思义,可以装下任何对象的“大小”,比如在 32 位环境下,地址空间中不可能存在多于 2^32 个唯一的对象,一个对象的大小也不可能超过 2^32 字节,所以 size_t 做成 uint32_t 就可以。需要存大小、数量时就用这货。
    ptrdiff_t 顾名思义,可以装下任意两个指针相减的结果,需要存偏移时就用这货。(不过 C 标准里面貌似没有保证,毕竟真正存差值需要 wordsize+1 位 …)
    毕竟如果是 32 位环境,用 64 位数存数组有多少个元素实在太过奢侈了,这时候根据大道至简的原则,就可以加一个类型叫 int 。

    这只是一个猜想,因为 Go 的所谓 spec 实在太大道至简了:
    > uint either 32 or 64 bits
    > int same size as uint
    反正在这两句话我是没找着“在 64 位处理器上占 64 位,在 32 位处理器上面占 32 位”的保证。因为他把这玩意写在后面 builtin functions 部分了:“The built-in functions len and cap take arguments of various types and return a result of type int. The implementation guarantees that the result always fits into an int.”,然后就有了这个 https://yourbasic.org/golang/int-vs-int64/ 。也就是说这个类型和它的角色并不直接关联,可能本来设计者的想法就是从 C 里面随便捣鼓来的 …

  • 資深大佬 : secondwtq

    噢对了补充下,我知道做优化的时候有至少一种情况会把 32 位数故意 widen 成 64 位,就是频繁转换的时候。
    具体来说,是一个循环的 induction variable ( https://en.wikipedia.org/wiki/Induction_variable )被定义为 32 位,但是使用时总是先 cast 成 64 位再使用,这种情况用 64 位数代替原来的 induction variable 可以省去转换的开销,并且就一两个变量一般都放寄存器里面,做起来才值得。
    (嘛不过我只是观察到这么一种行为,并没有找到对应的参考,也没有仔细看相关的代码 …)

  • 資深大佬 : douyacun

    自 2008 年 1 月起,Ken Thompson 就开始研发一款以 C 语言为目标结果的编译器来拓展 Go 语言的设计思想。

    c 有 go 就有了,因为顺手~

    grpc 就果断抛弃了 int

  • 主 資深大佬 : jiangwei2222

    @secondwtq 多谢大佬解释

  • 資深大佬 : INCerry

    那你可以用 C# C#在 64 位或者 32 位系统中 int 都是 Int32

  • 資深大佬 : binlearn

    如果我没有猜错,这应该是不同平台“字节对齐”的原因。用 int 能保证字节对齐

  • 資深大佬 : coolesting

    类型细分化,按需分配内存,工作更效率,和 rust 的设计同出一策,所以这两门语言在未来肯定会称霸一方。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具