与矢量量化相比,C++矢量实现低效率

2024-03-28 12:40:06 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我做的一个比较。np.argsort在由1000000个元素组成的float32数组上计时。在

In [1]: import numpy as np

In [2]: a = np.random.randn(1000000)

In [3]: a = a.astype(np.float32)

In [4]: %timeit np.argsort(a)
86.1 ms ± 1.59 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
<>这里是一个C++程序,但在向量上引用的是this answer。在

^{pr2}$

它打印Finished in 525.908 milliseconds.,而且比numpy版本慢得多。有人能解释一下是什么让np.argsort这么快吗?谢谢。在


Edit1:np.__version__返回运行在Python 3.6.6 |Anaconda custom (64-bit)和{}上的1.15.0打印8.2.0。操作系统是Manjaro-Linux。在


Edit2:我试图在g++中使用-O2-O3标志进行编译,结果在216.515毫秒和205.017毫秒内得到。这是一个改进,但仍然比numpy版本慢。(Referring to this question这被删除了,因为我错误地在没有拔下笔记本电脑直流适配器的情况下运行测试,这会导致测试速度减慢。在公平竞争中,C阵列和矢量版本的性能相当(大约需要100毫秒)。在


Edit3:另一种方法是用类C数组替换vector:float numbers[1000000];。之后,运行时间约为100ms(+/-5ms)。完整代码:

#include <iostream>
#include <vector>
#include <cstddef>
#include <algorithm>
#include <opencv2/opencv.hpp>
#include <numeric>
#include <utility>
int main()
{
  //std::vector<float> numbers;
  float numbers[1000000];
  for (int i = 0; i != 1000000; ++i) {
    numbers[i] = ((float)rand() / (RAND_MAX));
  }

  double e1 = (double)cv::getTickCount();

  std::vector<size_t> idx(1000000);
  std::iota(idx.begin(), idx.end(), 0);

  std::sort(idx.begin(), idx.end(), [&numbers](const size_t &a, const size_t &b)
                                               { return numbers[a] < numbers[b];});

  double e2 = (double)cv::getTickCount();
  std::cout << "Finished in " << 1000 * (e2 - e1) / cv::getTickFrequency() << " milliseconds." << std::endl;
  return 0;
}

Tags: in版本numpysizeincludenpfloatcv
2条回答

创意:

  • 不同的基础算法:。np.argsort默认使用快速排序,C++中的实现可能取决于编译器。

  • 函数调用开销:我不确定C++编译器是否内联了比较函数。如果不是,调用此函数也可能会带来一些开销。不是this post

  • 编译器标志?

我用10000000项来衡量你的实现。大约花了1.7秒。在

现在我介绍了一个班级

class valuePair {
  public:
    valuePair(int idx, float value) : idx(idx), value(value){};
    int idx;
    float value;
};

with初始化为

^{pr2}$

而排序比所做的还要多

std::sort(pairs.begin(), pairs.end(), [&](const valuePair &a, const valuePair &b) { return a.value < b.value; });

这段代码将运行时间缩短到1.1秒。我认为这是由于缓存的一致性更好,但与python的结果仍然相差甚远。在

相关问题 更多 >