【问题标题】:What numeric type to choose for small loop counters? [closed]为小型循环计数器选择什么数字类型? [关闭]
【发布时间】:2013-06-14 22:32:46
【问题描述】:

考虑 int 在内存中占用 4 个字节。

要了解我在寻找什么,请看这个例子:

for(x=0;x<10;x++) //do something

在这个指令中我知道x的值小于11

我看过很多代码,大多数人将 x 声明为 int

为什么我们不应该或为什么大多数人不将 x 声明为 short 甚至像 char !!

我想到了原因,找到了这个解释,例如:

short s=5;

s 在内存中占用 2 个字节,我所知道的是编译器将 5 视为 int 所以要把5换成s5应该转成short才对!!

-> 所以这条指令占用更少的内存但更多的工作

int i=5;

这里 i 占用 4 个字节但不需要对话(5 是一个 int

-> 所以这条指令做的工作更少,但占用更多的内存

原因和我想的一样!!

我希望我的问题很清楚

【问题讨论】:

  • in this for instruction I know that the value of x is less than 11,即使你是对的,x 也小于 10
  • 将此类微优化留给优化编译器(例如gcc -O2)。他们做的比你能做的要好。关注代码的正确性和可读性。
  • int 通常是寄存器宽度,因此分配给 char 或 short 实际上可能比分配给 int 需要更多的工作。
  • @zmo 在评估最终(失败)条件时,x 确实是 10,并且需要足够大以容纳它。
  • @zmo :Kevin 和 LightnessRacesinOrbit 的观点是 10 不小于 10。但 10 小于 11。

标签: c++ c char int short


【解决方案1】:

最好的理由 - 可读性。如果我看到一个循环遍历shortchar,我会花一些时间找出原因。 int 更直观,因为它是最常用的迭代类型(甚至比 iteratorsize_t 更常用)。

【讨论】:

    【解决方案2】:

    不,不完全。如果你有一个半合理的编译器,它会正确处理这个问题。如果您非常担心内存使用情况,请使用 short 并保留它。

    int 可能更好,因为它通常是寄存器的大小。这在某些 CPU 架构上可能更有效。

    请参阅this 问题。

    【讨论】:

      【解决方案3】:

      有时通过选择小于int 的算术类型来微优化内存使用是有意义的。但这是有代价的,因为从形式上讲,该值被提升为 int 以对其进行算术运算,然后转换回较小的类型。 int 是目标平台的自然大小,因此几乎总是最好只使用它,特别是因为每个未来的维护者都必须弄清楚为什么有人会写出如此不自然的代码。

      【讨论】:

        【解决方案4】:

        您对事物的表面外观考虑太多了。现实与此不同。

        例如,您担心循环变量占用的内存。但是,在许多循环中,循环变量永远不会存储在内存中。相反,它将被保存在寄存器中。 CPU 中的寄存器数量是有限的,但是变量不能占用半个寄存器(通常——x86 那里有点奇怪),所以无论你使用 int、short 还是 char,反正你可能会丢失一个完整的寄存器。所以你不会通过减小变量来节省任何东西。

        类似的假设是,将整数文字分配给 short 比分配 int 需要更多的工作。这里的问题是假设编译器将生成在运行时进行某种转换的代码,而首先生成执行简单事情的代码(只需将文字存储到内存位置)要简单得多。

        【讨论】:

          【解决方案5】:

          如果您必须在内存中存储数百万个数字,并且每个数字可能介于 0 和 11 之间,那么您会关心内存。在循环中,变量很可能存储在 CPU 寄存器中,这意味着它是例如 x86 上的 32 位或 x86_64 上的 32 到 64 位等。所有“较小”的整数都将零扩展为 32还是 64 位。

          int 简单易读,所以很多人都使用它。但是,如果您必须担心性能或提示编译器有关大小限制,请使用“(u)int_fast_*”类型(即uint_fast8_t

          【讨论】:

            【解决方案6】:

            当您需要循环获取更大的编号时,您可能会遇到代码。比char 甚至short 所能承受的次数还要多。这可能是当您为诸如数据库之类的系统进行编码时的情况,其中循环虽然数量很大。为了更安全,最好将循环变量作为'int'。还有一件事,如果您将这样的循环用于Delay_ms() 函数之类的东西,并且如果您尝试将循环变量限制为char,那么您将必须有嵌套循环,或者调用相同的Delay_ms() 函数一次又一次。

            【讨论】:

            • @Vlad Lazarenko 点了!谢谢
            【解决方案7】:

            “纯整数具有执行环境架构所建议的自然大小”1,这意味着在典型情况下,纯整数是对处理器施加最少工作的类型操纵和工作。简而言之,int 是您在没有充分理由使用其他东西时通常想要使用的默认类型。

            还请注意,在引用的情况下使用shortchar 减少内存使用很可能完全是虚幻的。在典型的情况下,我们可以期望一个循环索引变量无论如何都会被分配到一个寄存器中,所以不管我们关心多少位,在任何情况下,这个变量基本上都占据了整个寄存器。如果它不在寄存器中,它通常会在堆栈上,并且在大多数情况下,堆栈上项目的大小也是固定的(32 位架构上的 32 位,64 位架构上的 64 位等.) 因此分配单个char(例如)可以/将经常最终使用与int 一样多的内存。


            1. §3.9.1/2 in n1337,但所有 C 和 C++ 标准一直追溯到原始 ANSI C89 标准的措辞几乎相同,尽管部分编号已更改。

            【讨论】:

            • 这实际上是唯一的答案,它客观地正确回答了问题,并且不会在提问者身上玩自作聪明(“别管微优化”,“做this 而不是 that" 等)我希望在 SO 中有更多这样的答案。
            • 不幸的是,int 必须至少为 16 位宽,这意味着这不适用于 8 位架构。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-04-07
            • 2023-03-23
            • 1970-01-01
            • 1970-01-01
            • 2019-03-26
            • 2021-02-26
            • 1970-01-01
            相关资源
            最近更新 更多