tjw*_*992 2 c++ python performance
在将其转换为C ++之前,我一直在使用Python进行一些快速原型制作,发现在某些情况下,Python代码的运行速度明显快于C ++代码!
考虑一下用Python和C ++编写的简单循环:
蟒蛇:
import numpy as np
import datetime
N = 16777216
f_s = 8000.0
t_s = 1/f_s
y = np.empty(N)
start = datetime.datetime.now()
for n in range(0,N):
y[n] = np.sin(2*np.pi*1000*n*t_s) + 0.5*np.sin(2*np.pi*2000*n*t_s + 3*np.pi/4)
stop = datetime.datetime.now()
duration = stop - start
print("duration ", duration.microseconds, " microseconds")
Run Code Online (Sandbox Code Playgroud)
输出:
持续时间842000微秒
C ++:
#include <chrono>
#include <cmath>
#include <iostream>
#include <vector>
int main() {
int N = 16777216;
int f_s = 8000;
double t_s = 1.0 / f_s;
std::vector<double> x(N);
auto start = std::chrono::high_resolution_clock::now();
for (int n = 0; n < N; ++n)
{
x[n] = std::sin(2 * M_PI * 1000 * n * t_s) + 0.5 * std::sin(2 * M_PI * 2000 * n * t_s + 3 * M_PI / 4);
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
std::cout << "duration " << duration.count() << " microseconds." << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
持续时间1993000微秒。
Python代码似乎确实要花费大量的启动时间,而C ++代码会立即运行。(也许Python解释器在启动时需要花费很长时间进行一些优化?)但是尽管如此,但一旦Python代码运行,循环本身在Python中的运行速度就会大大提高。
这让我大吃一惊,但我似乎无法弄清楚Python如何如此快地运行此循环。我什至尝试在不同的优化级别上编译C ++代码,以查看编译器是否以某种方式在优化方面做得不好。上面的C ++示例经过编译,g++ -O3以改善优化效果。当没有切入时,我什至尝试g++ -Ofast将运行时间提高到1205000微秒,但仍然比Python循环慢得多!
我已经尝试了Googling,但找不到任何真正的解释……这怎么可能发生?如何从C ++循环中获得更好的性能?我希望我可以和Python循环一样快,甚至更快。
我在跑步 Python 3.7.2
C ++的例子是使用编译g++.exe (MinGW.org GCC-6.3.0-1) 6.3.0与-O3编译器开关,以提高优化。
我还尝试在Linux环境中编译C ++代码,g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)结果相似。
big*_*_29 12
您使用的microseconds组件不timedelta正确。它仅为您提供时间测量的亚秒级部分,而不是总经过的微秒级。此代码突出了您的错误
from datetime import datetime, timedelta
start = datetime(2019, 1, 1, 12, 0, 0, 0 )
end = datetime(2019, 1, 1, 12, 0, 1, microsecond=500000 )
diff = end - start
print('Total duration=',diff)
print('Total seconds=', diff.total_seconds())
print('microseconds=', diff.microseconds)
Run Code Online (Sandbox Code Playgroud)
from datetime import datetime, timedelta
start = datetime(2019, 1, 1, 12, 0, 0, 0 )
end = datetime(2019, 1, 1, 12, 0, 1, microsecond=500000 )
diff = end - start
print('Total duration=',diff)
print('Total seconds=', diff.total_seconds())
print('microseconds=', diff.microseconds)
Run Code Online (Sandbox Code Playgroud)
使用total_seconds1e6并乘以1e6,或者只是更改测试以在几秒钟内报告结果。
注意 C ++应该很容易赢得胜利。循环具有在编译时已知的固定数量的迭代,并且所有计算都不相互依赖。一个好的优化C ++编译器应该对循环进行分块或部分展开,并使用SSE指令并行执行少量计算。
| 归档时间: |
|
| 查看次数: |
124 次 |
| 最近记录: |