【问题标题】:When should one be careful using a bitset in place of a bool array?什么时候应该小心使用 bitset 代替 bool 数组?
【发布时间】:2009-12-07 02:55:33
【问题描述】:

我正在开发一个手机应用程序,我看到了提高性能的潜在机会。在整个代码中,我使用 bool 数组来跟踪哪些对象是活动的。例如,我会通过执行以下操作来检查第 i 个 MyObject 是否处于活动状态:

if(activeMyObjects[i]){ // it's active so do something... }

由于我的对象的最大数量在 [5,20] 范围内,我想我可以用单个整数“activeMyObjects”形式的 bitset 替换 activeMyObjects bool 数组。然后我可以执行以下操作:

// check if ith object is active
if(activeMyObjects & (1 << i)){ // it's active... }

// activate the ith object
activeMyObjects |= (1 << i);

// reset all myObjects to inactive
activeMyObjects = 0;

// and so on...

是否有任何时候切换到 bitset 会降低性能?我使用的语言是 c。另请注意,此代码的调用频率很高(频率范围为 30 - 60 Hz)。

编辑: 另一条信息:位集还有另一个优点,即我可以轻松判断是否有任何对象处于活动状态。所以我可以跳过一个循环,通过首先检查 if(activeMyObjects) 来检查每个项目以查看它是否处于活动状态。当我使用数组时,这更棘手......我的方法是有一个额外的计数器 int,每当激活 MyObject 时递增,每当停用 MyObject 时递减......这样我只需检查 if(activeMyObjectsCount > 0)在我检查每个循环之前。

【问题讨论】:

    标签: c performance


    【解决方案1】:

    根据分配 bitset 的频率,您可以很容易地以 bitset 版本占用更多内存。

    访问特定位的代码比访问整个内存字节的代码大得多 - 如果这些数组只有少数几个,但经常访问它,你会得到更小的占用空间就像它一样。

    【讨论】:

    • 位集在程序开始时在堆栈上分配一次。他们被非常频繁地访问。对bitset的操作是:设置第i位,检查第i位是否设置,取消设置第i位,取消所有位。鉴于此信息,您会建议使用数组还是位集?
    • 你真的只需要自己测试一下。我知道将开发时间投入到不确定的价值中是很糟糕的,但这非常依赖于实现。它真的可以去任何一种方式。它取决于编译器优化、原生芯片组命令、缓存结构以及 CPU/缓存/数据的相对速度。如果这里有人可以权威地为您回答这个问题,我真的会感到惊讶,特别是因为您没有列出任何这些变量。
    • 如果它们被分配一次并且经常被访问,它将使用更少的内存来保持数组。然后加载一个布尔值是一条指令 - 而使用位集,您正在查看三个(加载、移位、掩码)。在性能方面,您需要在目标硬件上对每个选项进行基准测试,以便了解结果。
    【解决方案2】:

    您不会在大多数平台上获得任何性能。您将节省的是内存占用。

    【讨论】:

      【解决方案3】:

      不。归根结底,这是一个简单的整数移位,比所有帐户的数组访问成本更低。请注意将位集转换为第三集(可能是活动的、非活动的和未定义的),或者尝试向每个条目添加数据现在在不重构的情况下是不可能的。

      【讨论】:

      • 另外,如果你有超过 32 个对象,你需要将你的 bitset 扩展为一个 int 数组。在这种情况下,您仍将访问数组条目,但会节省空间。
      【解决方案4】:

      如果速度比内存占用更重要(因为这是整个移动应用程序),那么您可以将掩码存储在数组中,并将它们作为 activeMyObjects & mask[i] 访问。

      【讨论】:

      • 如果速度很关键,那么最好使用命名常量而不是掩码数组。
      【解决方案5】:

      有人告诉我,一些 PowerPC 芯片(不知道是不是全部 - 例如参见 this question)在执行可变长度位移时很慢,就像您使用 (1 &lt;&lt; i) 指令所做的那样.因此,在这些芯片上,bitset 的运行速度似乎比 bool 数组慢得多。

      这对你来说可能不是问题,但这是一个有趣的小案例 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-12
        • 2023-04-02
        • 2011-04-15
        • 2017-04-10
        • 2012-03-19
        • 2018-05-12
        • 2018-12-11
        • 1970-01-01
        相关资源
        最近更新 更多