将int数组与指向bools的指针复制

时间:2010-12-03 21:30:55

标签: c++ arrays optimization boolean int

我正在开发一个程序,需要将数组复制数千次/数百万次。现在我有两种表示数组中数据的方法:

一系列整数:

int someArray[8][8];

其中someArray[a][b]的值可以是0,1或2,或

指向布尔值的指针数组:

bool * someArray[8][8];

其中someArray[a][b]可以是0(空指针),否则*someArray[a][b]可以是真(对应于1),或者是假(对应于2)。

哪个数组的复制速度会更快(是的,如果我指向booleans数组,我每次复制数组时都要声明新的bool)?

7 个答案:

答案 0 :(得分:5)

哪个复制速度更快就是这一点,分配和释放条目的开销,以及取消引用指针来检索每个值,对于bool*方法,都会影响复制的成本。

如果您只有3个可能的值,请使用char数组,其复制速度比int快4倍。好吧,这不是一个科学证明的陈述,但阵列小4倍。

答案 1 :(得分:3)

实际上,两者在复制方面看起来大致相同 - 一个32位整数数组与一个32位指针数组。如果编译为64位,那么指针可能会更大。

顺便说一句,如果你存储指针,你可能不希望为该数组的每个字段都有一个“bool”的SEPARATE实例,对吗?那肯定会慢得多。

如果您想要快速复制,请尽可能减小尺寸,或者:

  • 使用char代替int
  • 设计一个自定义类,对该数组进行位操作。如果将一个值表示为两个位 - “空”位和“值 - 如果不为空”位,那么对于整个64个值的数组,您需要128位= 4个整数。这肯定会被快速复制!但访问任何单个位都会有点复杂 - 只需几个周期。

好的,你让我很好奇:)我卷起了这样的东西:

struct BitArray {
public:
    static const int DIMENSION = 8;

    enum BitValue {
        BitNull = -1,
        BitTrue = 1,
        BitFalse = 0
    };
    BitArray() {for (int i=0; i<DIMENSION; ++i) data[i] = 0;}
    BitValue get(int x, int y) {
        int k = x+y*DIMENSION; // [0 .. 64)
        int n = k/16;          // [0 .. 4)
        unsigned bit1 = 1 << ((k%16)*2);
        unsigned bit2 = 1 << ((k%16)*2+1);

        int isnull = data[n] & bit1;
        int value = data[n] & bit2;
        return static_cast<BitValue>( (!!isnull)*-1 + (!isnull)*!!value );
    }
    void set(int x, int y, BitValue value) {
        int k = x+y*DIMENSION; // [0 .. 64)
        int n = k/16;          // [0 .. 4)
        unsigned bit1 = 1 << ((k%16)*2);
        unsigned bit2 = 1 << ((k%16)*2+1);
        char v = static_cast<char>(value);

        // set nullbit to 1 if v== -1, else 0
        if (v == -1) {
            data[n] |= bit1;
        } else {
            data[n] &= ~bit1;
        }

        // set valuebit to 1 if v== 1, else 0
        if (v == 1) {
            data[n] |= bit2;
        } else {
            data[n] &= ~bit2;
        }
    }
private:
    unsigned data[DIMENSION*DIMENSION/16];
};

8x8数组的此对象的大小为16字节,与使用char array[8][8]和256字节int array[8][8]的解决方案的64字节相比,这是一个很好的改进

这可能是一个人可以去的地方,而不需要深入研究更大的魔力。

答案 2 :(得分:1)

我想说你需要重新设计你的程序。在int x[8][8]bool *b[8][8]之间转换“数百万”次无法“正确”,但您对“正确”的定义不严格。

答案 3 :(得分:0)

您的问题的答案将与数据类型的大小相关联。通常bool是一个字节,而int则不是。指针的长度取决于体系结构,但这些天通常是32位或64位。

不考虑缓存或其他特定于处理器的优化,更大的数据类型需要更长时间才能复制。

鉴于您有三种可能的状态(0,1,2)和64个条目,您可以用128位表示整个结构。使用一些实用程序例程和两个无符号64位整数,可以非常快速地有效地复制数组。

答案 4 :(得分:0)

我不是百分百肯定,但我认为它们将花费大致相同的时间,但我更喜欢使用堆栈分配(因为动态分配可能需要一些时间来寻找可用空间)。

考虑使用short类型而不是int,因为您不需要多种数字。

我认为如果你真的想要最大速度可能会更好,因为使用错误顺序的for循环,编译器用来存储多维数组(原始主要或列主要)可能会导致性能惩罚!

答案 5 :(得分:0)

如果不太了解如何使用数组,这是一个可能的解决方案:

typedef char Array[8][8];
Array someArray, otherArray;
memcpy(someArray, otherArray, sizeof(Array));

这些数组只有64个字节,应该可以相当快地复制。您可以将数据类型更改为int,但这意味着至少复制256个字节。

答案 6 :(得分:0)

使用指针“复制”此数组需要深层复制,因为否则更改副本将影响原始数据,这可能不是您想要的。由于内存分配开销,这将极大地降低速度。

您可以使用boost::optional来表示“可选”数量 - 这是您在此处添加间接级别的唯一原因。在现代C ++中很少有情况下原始指针真的是最好用的东西:)但是,因为你只需要一个char来存储值{0,1,2},这很可能在空间方面更好。我很确定sizeof(boost::optional<bool>) > 1,虽然我没有测试过它。如果他们专门为此我会留下深刻的印象:)

您甚至可以对2位数量的数组进行位打包,或者使用两个位打包的布尔数组(一个“掩码”,然后是另一组实际的真假值) - 例如使用std::bitset 。这肯定会节省空间并减少复制时间,尽管它可能会增加访问时间(假设您确实需要一次访问一个值)。