在c ++中改进2个数组的并集

时间:2012-01-25 01:26:53

标签: c++ arrays performance

有没有办法让c ++中的2个数组A和B的联合更快(给定n)? 我有想法,但看不到其他方式......

double *A = (double *)malloc( n*n *sizeof(double));
double *B = (double *)malloc(   n *sizeof(double));
double *U = (double *)malloc((n*n+n) *sizeof(double));


int i=0, ci=0;
for (i = 0; i <n*n; i++)
    U[ci++] = A[i];
for (i = 0; i < n; i++)
    U[ci++] = B[i];

3 个答案:

答案 0 :(得分:7)

没有渐近更好的方法来做到这一点,因为你必须复制每个元素一次。但是,您可以通过使用memcpy等批量复制操作为您完成工作,从而做得更好:

double *A = (double *)malloc( n*n *sizeof(double));
double *B = (double *)malloc(   n *sizeof(double));
double *U = (double *)malloc((n*n+n) *sizeof(double));

/* Copy over A onto U. */
memcpy(U, A, n * n * sizeof(double));

/* Append B to U. */
memcpy((char*)U + n * n * sizeof(double), B, n * sizeof(double));

这可能更快,因为复制字节的逻辑可以手工优化。

你用C ++标记了这个问题,虽然它看起来更像C代码。也就是说,如果你使用C ++,你可以这样写(使用std::copy):

double *A = new double[n * n];
double *B = new double[n];
double *U = new double[n * n + n];

std::copy(A, A + n * n, U);
std::copy(B, B + n,     U + n * n);

或者,更好的是,使用std::vector没有暴露的内存管理或指针:

vector<double> A(n * n);
vector<double> B(n);

vector<double> U;
U.reserve(A.size() + B.size());
U.insert(U.end(), A.begin(), A.end());
U.insert(U.end(), B.begin(), B.end());

希望这有帮助!

答案 1 :(得分:2)

由于你所做的只是连接两个内存块,你可以使用memcpy

double *A = (double *)malloc( n*n *sizeof(double));
double *B = (double *)malloc(   n *sizeof(double));
double *U = (double *)malloc((n*n+n) *sizeof(double));
memcpy(U, A, n*n *sizeof(double));
memcpy(U+n*n *sizeof(double), B, n *sizeof(double));

如果硬件提供单指令复制,您可以从中获得一些性能提升。另一方面,优化器可能会计算出您正在做的事情,并为您调用memcpy来替换您的代码。

答案 2 :(得分:0)

如果真的应该是C ++而不是C,那么你应该使用像std::vector这样的C ++结构。

我相信代码看起来像(虽然我没有测试过):

size_t n = 100;
std::vector A(n*n);
std::vector B(n);
std::vector U;

U.reserve( A.size() + B.size() );
std::copy(A.begin(), A.end(), std::back_inserter(U));
std::copy(B.begin(), B.end(), std::back_inserter(U));

如果您实际上是指联合集中没有重复数字的联合,那么您需要对AB进行排序,然后使用std::set_union函数。