我正在开发一个程序,需要将数组复制数千次/数百万次。现在我有两种表示数组中数据的方法:
一系列整数:
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)?
答案 0 :(得分:5)
哪个复制速度更快就是这一点,分配和释放条目的开销,以及取消引用指针来检索每个值,对于bool*
方法,都会影响复制的成本。
如果您只有3个可能的值,请使用char
数组,其复制速度比int
快4倍。好吧,这不是一个科学证明的陈述,但阵列将小4倍。
答案 1 :(得分:3)
实际上,两者在复制方面看起来大致相同 - 一个32位整数数组与一个32位指针数组。如果编译为64位,那么指针可能会更大。
顺便说一句,如果你存储指针,你可能不希望为该数组的每个字段都有一个“bool”的SEPARATE实例,对吗?那肯定会慢得多。如果您想要快速复制,请尽可能减小尺寸,或者:
char
代替int
或好的,你让我很好奇:)我卷起了这样的东西:
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
。这肯定会节省空间并减少复制时间,尽管它可能会增加访问时间(假设您确实需要一次访问一个值)。