布尔标志与未签名的字符标志

Bool Flags vs. Unsigned Char Flags

本文关键字:标志 字符 布尔      更新时间:2023-10-16

免责声明:如果我在这篇文章中提出任何虚假声明,请纠正我。

考虑一个包含八个 bool 成员变量的结构。

/*
* Struct uses one byte for each flag.
*/
struct WithBools
{
bool f0 = true;
bool f1 = true;
bool f2 = true;
bool f3 = true;
bool f4 = true;
bool f5 = true;
bool f6 = true;
bool f7 = true;
};

分配给每个变量的空间长度为一个字节,如果变量仅用作标志,这似乎是一种浪费。就变量而言,减少这种浪费空间的一种解决方案是将八个标志封装到无符号字符的单个成员变量中。

/*
* Struct uses a single byte for eight flags; retrieval and
* manipulation of data is achieved through accessor functions.
*/
struct WithoutBools
{
unsigned char getFlag(unsigned index)
{
return flags & (1 << (index % 8));
}
void toggleFlag(unsigned index)
{
flags ^= (1 << (index % 8));
}
private:
unsigned char flags = 0xFF;
};

通过按位运算符检索和操作标志,结构为用户提供检索和操作标志的接口。虽然标志大小已减小,但我们现在有两个额外的方法来增加结构的大小。我不知道如何对这种差异进行基准测试,因此我无法确定上述结构之间的任何波动。

我的问题是:

1)这两种结构之间的空间差异可以忽略不计吗?

2)一般来说,这种通过将布尔集合压缩到单个字节中来"优化"布尔集合的方法是一个好主意吗?无论是在嵌入式系统环境中还是在其他方面。

3)C++编译器是否会进行这样的优化,在可能和适当的情况下压缩布尔集合。

我们现在

有两个额外的方法,它们增加了 结构

方法是代码,不会增加结构的大小。只有数据才能构成结构的大小。

3)C++编译器是否会进行这样的优化,以压缩 在可能和适当的情况下收集布尔值。

这声音响亮了。不允许编译器更改数据类型。

1)这两个结构之间的空间差异是 微不足道?

不,这两种方法之间肯定存在大小差异。

2)一般来说,这种"优化"布尔集合的方法 将它们压缩成一个字节是个好主意吗?要么在 嵌入式系统上下文或其他。

一般来说,对标志进行建模的惯用方法是在无符号整数中进行逐位操作。根据所需的标志数量,您可以使用std::uint8_tstd::uint16_t等。

但是,对此进行建模的最常见方法不是像您所做的那样通过索引,而是通过掩码。

这两个结构之间的空间差异可以忽略不计吗?

这取决于您要存储多少值以及必须存储它们多少空间。 大小差异为 1 到 8。

一般来说,这种通过将布尔集合压缩到单个字节来"优化"布尔集合的方法是一个好主意吗?无论是在嵌入式系统环境中还是在其他方面。

同样,这取决于有多少值和多少空间。 另请注意,处理位而不是字节会增加代码大小和执行时间。

许多嵌入式系统的RAM相对较小,闪存量很大。 代码存储在闪存中,因此可以忽略增加的代码大小,节省的内存在小型RAM系统上可能很重要。

C++编译器是否会进行这样的优化,在可能和适当的情况下压缩布尔值的集合。

假设可以。 我认为这是一种积极的空间优化,以牺牲执行时间为代价。

STL有一个专门用于vector<bool>的领域,出于性能原因,我经常避免这样做 -vector<char>速度要快得多。