繁体   English   中英

如何优化 C++ 中的基数排序算法?

[英]How to optimize this Radix-Sort algorithm in C++?

我正在处理优化 C++ 中的基数排序代码的任务,我需要减少执行时间,我的代码正在运行,它看起来像这样:

void RadixSort::RadixSortNaive(std::vector<long> &Arr) {

long Max_Value = findMax(Arr);

    int Max_Radix = 1;
while (1) {
  if (Max_Radix >= Max_Value) break;
  Max_Radix = Max_Radix*radix_;
}

for (int i = 1; i < Max_Radix; i = i*radix_) {
  for (int j = 0; j < key_length_; j++) {
    int K;
    if (Arr[j] < i) K = 0;
    else K = (Arr[j] / i) % radix_;
    Q[K].push(Arr[j]);
  }

  int idx = 0;
  for (int j = 0; j < radix_; j++) {
    while (Q[j].empty() == 0) {
      Arr[idx] = Q[j].front();
      Q[j].pop();
      idx++;
    }
  }
}
class RadixSort{
public :

  void setConfig(int key_length, int radix) {
    key_length_ = key_length;
    radix_ = radix;
    for (int i = 0; i < radix_; i++) {
      Q.push_back(std::queue<long>());
    }
  }

  long findMax(std::vector<long> Arr) const {
    long Max = 0;
    for (int i = 0; i < key_length_; i++) {
      if (Max < Arr[i])
        Max = Arr[i];
    }
    return Max;
  }

  void RadixSortNaive(std::vector<long> &Arr);
  void RadixSortStudent(std::vector<long> &Arr);

private:
  int key_length_;
  int radix_;
  std::vector<std::queue<long>> Q;
};
}

但是,我确信仍有改进的余地。 我一直在尝试使用 OMP 库实现并行化,但似乎没有任何效果。 有什么办法可以改进以前的代码吗? 也许改进循环或任何其他代码优化技术。

正如评论中所建议的,第一件事是让 API 正确。

findMax可以替换为std::max_element( ) ,它使用迭代器,并且不复制输入。

其他可疑的事情是Q[K].push(Arr[j]); . 如果 memory 允许,至少在每个队列中保留最大数量的元素——否则队列在调整大小时需要复制旧数据。

然后,如果可能,使用没有超出范围检查的原始指针,您可以push()pop()auto popped = *tail++*head++ = new_element; 我的观察是,虽然 STL 已正确实现并且可以快速开发,但与已知的 ZA81259CEF8E959C624DF1D456E5D327 分配相比,插入中动态 memory 分配的支持实际上总是会降低性能。

第三件事是将基数专门化为 2 的幂,因为现在除法是强度减少到移位,模数是强度减少到逻辑和(通过一些常数,需要计算)。

特别是当 radix 是 2 的幂时,可能还有其他情况,我想有条件地计算K==0是没有用的: if (Arr[j] < i) K = 0; .

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM