布尔标志与未签名的字符标志
Bool Flags vs. Unsigned Char Flags
免责声明:如果我在这篇文章中提出任何虚假声明,请纠正我。
考虑一个包含八个 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_t
、std::uint16_t
等。
但是,对此进行建模的最常见方法不是像您所做的那样通过索引,而是通过掩码。
这两个结构之间的空间差异可以忽略不计吗?
这取决于您要存储多少值以及必须存储它们多少空间。 大小差异为 1 到 8。
一般来说,这种通过将布尔集合压缩到单个字节来"优化"布尔集合的方法是一个好主意吗?无论是在嵌入式系统环境中还是在其他方面。
同样,这取决于有多少值和多少空间。 另请注意,处理位而不是字节会增加代码大小和执行时间。
许多嵌入式系统的RAM相对较小,闪存量很大。 代码存储在闪存中,因此可以忽略增加的代码大小,节省的内存在小型RAM系统上可能很重要。
C++编译器是否会进行这样的优化,在可能和适当的情况下压缩布尔值的集合。
假设可以。 我认为这是一种积极的空间优化,以牺牲执行时间为代价。
STL有一个专门用于vector<bool>
的领域,出于性能原因,我经常避免这样做 -vector<char>
速度要快得多。
- C++字符*缓冲区的大小
- HEX值到wchar_t字符(UTF-8)的转换
- 为什么 Serial.println(<char[]>);返回随机字符?
- 我的字符计数代码计算错误.为什么
- 字符串-C++后显示的随机字符
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 如何在C++中从字符串中分割字符
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 指向指向字符数组的指针数组的指针
- 如何用转义符替换字符串中的所有特殊字符
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 比较字符数组
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 如何在C++中确定文本文件中的元素是字符还是数字
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 布尔标志与未签名的字符标志
- gzgetc在读取最后一个字符时设置EOF标志
- _带有_O_U8TEXT标志的wsopen_s,向缓冲区、中间字符和4个中间俄语字符返回0.VS2010