【问题标题】:improve union of 2 arrays in c++在 C++ 中改进 2 个数组的联合
【发布时间】:2012-01-25 01:26:53
【问题描述】:

有没有办法让 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];

【问题讨论】:

  • 嗯,你可以随时使用memcpy
  • 你所拥有的不是工会。也许你应该改写这个问题?
  • 啊,我看到您正在尝试合并两个数组,一个新数组 U 包含 AB

标签: c++ arrays performance


【解决方案1】:

没有一种渐近更好的方法可以做到这一点,因为您必须准确地复制每个元素一次。但是,您可以通过使用像 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());

希望这会有所帮助!

【讨论】:

  • @ruakh- D'oh。我应该更好地校对。又修了。我猜std::copymemcpy 工作方式不同,这相当令人惊讶。
  • 事实上我想避免 for 循环,你认为这个 std::copy 是否适用于非常大的数组,比如 1,000,000 个元素?
  • @cMinor- 是的 - std::copy 适用于任意大小的元素范围。
  • @cMinor:在内部,std::copy 是使用循环实现的。当然,所有的复制操作都是。
  • 但是内存复制?它会传递一块内存吗?让我们说一个内存地址的开始??
【解决方案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 替换你的代码。

【讨论】:

    【解决方案3】:

    如果这真的应该是 C++ 而不是 C,那么您应该使用 C++ 结构,例如 std::vector

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

    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 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-14
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 2016-12-09
      • 2013-06-19
      • 1970-01-01
      相关资源
      最近更新 更多