C:使用 char 比使用 int 更快吗?

Dus*_*via 0 c performance types integer char

由于 char 只有 1 个字节长,因此在处理 8 位 unsigned int 时使用 char 是否更好?

示例:我试图创建一个结构来存储颜色的 RGB 值。

struct color
{
  unsigned int r: 8;
  unsigned int g: 8;
  unsigned int b: 8;
};
Run Code Online (Sandbox Code Playgroud)

现在由于它是 int,所以在我的例子中它分配了 4 个字节的内存。但如果我用 unsigned char 替换它们,它们将按预期占用 3 个字节的内存(在我的平台中)。

Per*_*xty 6

不,也许有一点点。

首先,这是一个非常依赖平台的问题。然而,<stdint.h>引入标头是为了帮助解决这个问题。

一些硬件平台针对特定大小的操作数进行了优化,并且使用较小(按位大小)的操作数会产生开销,即使逻辑上较小的操作数需要较少的计算。

您应该发现这uint_fast8_t是最快的无符号整数类型,至少有 8 位(#include <stdint.h>要使用它)。这可能与您的问题分别是“是”或“否”相同unsigned charunsigned int取决于您的问题是“是”还是“否”(*)。

因此,我们的想法是,如果您注重速度,则可以使用uint_fast8_t,编译器将选择适合您目的的最快类型。

该方案有几个缺点。一是,如果您创建大量数据,性能可能会受到损害(并达到限制),因为您为此目的使用了“超大”类型。

在 4 字节int比 1 字节快的平台上char,您使用的内存大约是所需内存的 4 倍。如果您的平台很小或规模很大,这可能是一笔巨大的开销。

此外,您还需要小心,如果基础类型不是您期望的最小大小,那么某些计算可能会混淆。

uint_fast8_t对于无符号操作数,算术“时钟”整齐地排列,但如果实际上不是 8 位,则显然大小不同。

以下返回的内容取决于平台:

#include <stdint.h>

//...

int foo() {
   uint_fast8_t x=255; 
   ++x;
   if(x==0){
       return 1;
   }
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

处理潜在的超大类型的开销可能会收回你的收益。

我倾向于同意 Knuth 的观点,即“过早的优化是万恶之源”,并且我会说,只有在需要时才应该采用这种聪明才智。

现在先进行 typedeftypedef uint8_t color_comp;并让应用程序正常工作,然后再尝试削减几分之一秒的性能!

我不知道您的应用程序是做什么的,但可能它在 RGB 通道中不是计算密集型的,并且瓶颈(如果有)在其他地方。也许您会发现一些高负载计算值得处理uint_fast8_t转换和问题。

高德纳 (Knuth) 的智慧在于,无论如何,你可能直到稍后才知道它在哪里。

(*) 它可能是unsigned long或者确实是其他类型。唯一的限制是它是无符号类型且至少为 8 位。

  • 关于“uint_fastN_t”和“uint_leastN_t”的陷阱,您提出了一个非常好的观点——如果依赖于无符号溢出的环绕算术(例如8位计数器),则可能应该使用像“uint8_t”这样的精确宽度类型,无论某些平台上可能存在效率低下的情况。 (2认同)
  • @saxbophone 通常指定最小值而不是实际限制的整个 C 模型可能会导致问题。在包括汽车行业在内的许多行业中,您需要使用明确的尺寸,因为它们比聪明更安全! (2认同)