【问题标题】:Most effective way to store more booleans存储更多布尔值的最有效方法
【发布时间】:2011-06-02 13:48:50
【问题描述】:

我需要在 c 中的结构中存储四个布尔值。是的,我可以使用四个整数或将它们放入一个数组中,但我想做得更好一点。我在考虑一个像“0000”这样的整数,其中每个数字都代表布尔值,但是在编辑时我不能只编辑一个数字,对吗?这看起来也不完美……

感谢您的任何想法

【问题讨论】:

  • 定义“有效”。你的意思是最快的?最小的内存占用?最小的代码足迹?最优雅?
  • 什么对你来说“最有效”?占用更少的内存、快速、易用?
  • 抱歉没有包括在内,我的意思是使用更少的内存并且易于使用
  • 4 位被称为 nibble,只是为了帮助您与首席编程官一起改进行话 :-)

标签: c performance memory-management


【解决方案1】:

您可以使用位域结构:

struct foo {
  unsigned boolean1 : 1;
  unsigned boolean2 : 1;
  unsigned boolean3 : 1;
  unsigned boolean4 : 1;
};

然后您可以轻松地分别编辑每个布尔值,例如:

struct foo example;
example.boolean1 = 1;
example.boolean2 = 0;

【讨论】:

  • 太好了,看起来很完美。顺便说一句,我是否理解这些变量中的每一个都只占用一位?
  • 理论上是的。但是,由于内存填充,它很可能会占用更多。然而,它肯定比使用整数更节省内存。
  • 所描绘的四位将被填充以填充整个unsigned。在实践中unsigned char 可用于保存位字段,但如果struct 中有其他成员可能不会影响整体存储,因为这些成员根据通常有意义但可以的规则填充和对齐不能用一句话来形容。另请注意,可以用明显的方式描述多于一位的字段。
  • 顺便说一句,我还有更多问题。冒号后面的值(在本例中为 1)定义了位长,对吗?是否也可以添加默认值?我需要将其默认设置为 1 而不是 0。我试过“unsigned boolean2 = 1 : 1;”如此失败。它不是任何必要的东西,但它会使我的代码排列得更合理。
【解决方案2】:

可以使用

http://en.wikipedia.org/wiki/Stdbool.h

bool a = true;  // Could also be 'bool a = 1;'

【讨论】:

    【解决方案3】:

    使用像“0000”这样的 int 被称为使用位字段,并且在实践中经常使用。是的,您可以使用 bit shifting 编辑单个值。就个人而言,我宁愿将 int 用于位域结构,因为您可以扩展多达 32 个值(当然,如果您使用的是 32 位 int)而无需修改结构。

    【讨论】:

      【解决方案4】:
      struct _eMyBool
      {
          int m_iOne : 1;
          int m_iTwo : 1;
          int m_iThree : 1;
          int m_iFour : 1;
      } eMyBool;
      

      但是甚至不认为这是使用布尔值的最有效方式。

      因为为了处理这个而生成的附加汇编代码是有代价的!​​p>

      For example read this MSDN article

      AFAI 记得我认为获得内存的比率至少应为 7,因为在访问一位对齐成员时用于移位的附加代码的占用空间非常重要。

      This is the wikipedia article about data alignement.

      【讨论】:

      • MSDN 的文章很有意思,但是在 OP 的定义中,“最有效”的意思是“使用更少的内存,易于使用”。在这里,权衡主要是多一些 CPU 指令,而不是内存。
      • 我倾向于同意你的观点,但必须记住这个价格。也许不是这篇文章,但我清楚地记得 7 的比率。如果我没有获得太多内存,那么我认为位域方法是一种微优化,它“可能”真的是有代价的。如果对其中一个布尔值的访问是一个非常重复的操作,在分析应用程序时出现:毫无疑问我会删除位域。
      【解决方案5】:

      如果您要存储数百万个这些,请将其作为打包位进行。

      如果您需要每秒访问数百万次,请将其作为整数(或短裤或字符)进行。

      如果两者都不是,那没关系。

      如果两者兼而有之,那么您可能需要进行一些认真的性能调整。

      【讨论】:

        猜你喜欢
        • 2012-08-04
        • 2011-10-03
        • 2010-10-10
        • 2011-10-31
        • 1970-01-01
        • 2023-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多