这是我做的一个比较。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:我试图在这被删除了,因为我错误地在没有拔下笔记本电脑直流适配器的情况下运行测试,这会导致测试速度减慢。在公平竞争中,C阵列和矢量版本的性能相当(大约需要100毫秒)。在g++
中使用-O2
和-O3
标志进行编译,结果在216.515毫秒和205.017毫秒内得到。这是一个改进,但仍然比numpy版本慢。(Referring to this question)
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;
}
创意:
不同的基础算法:。
np.argsort
默认使用快速排序,C++
中的实现可能取决于编译器。函数调用开销:我不确定不是this postC++
编译器是否内联了比较函数。如果不是,调用此函数也可能会带来一些开销。编译器标志?
我用
10000000
项来衡量你的实现。大约花了1.7秒。在现在我介绍了一个班级
with初始化为
^{pr2}$而排序比所做的还要多
这段代码将运行时间缩短到1.1秒。我认为这是由于缓存的一致性更好,但与python的结果仍然相差甚远。在
相关问题 更多 >
编程相关推荐