我制作了两个用于将向量相加的函数,以便我可以将正弦波相加,其中一个使用 + 运算符相加,另一个使用 lambda 函数将它们相加,这使我更容易为多个操作创建函数。其中一个需要 5 微秒,另一个需要大约 17000 秒。
#include <iostream>
#include <vector>
#include <stdint.h>
#include <numbers>
#include <functional>
#include <chrono>
#include <cmath>
using i16 = int16_t;
constexpr float sample_rate = 44100;
std::vector<i16> sineWave(float frequency, float amplitude, float duration){
int sampleCount = duration*sample_rate;
std::vector<i16> samples(sampleCount);
for(float i = 0;i<sampleCount;i++){
samples[i] = static_cast<i16>(std::sin(2.0f*std::numbers::pi*frequency*(i/sample_rate))*amplitude);
}
return samples;
}
std::vector<i16> waveAdd(std::vector<i16>& wave1, std::vector<i16>& wave2){
if(wave1.size() > wave2.size()){
wave1.resize(wave2.size());
}
else if(wave2.size() > wave1.size()){
wave2.resize(wave1.size());
}
std::vector<i16> final(wave1.size());
for(size_t i = 0;i<wave1.size();i++){
final[i] = wave1[i]+wave2[i];
}
return final;
}
std::vector<i16> waveOperation(std::vector<i16>& wave1, std::vector<i16>& wave2, std::function<i16(i16,i16)> operation){
if(wave1.size() > wave2.size()){
wave1.resize(wave2.size());
}
else if(wave2.size() > wave1.size()){
wave2.resize(wave1.size());
}
std::vector<i16> final(wave1.size());
for(size_t i = 0;i<wave1.size();i++){
final[i] = operation(wave1[i],wave2[i]);
}
return final;
}
int main(){
auto a = sineWave(10000,1000,20);
auto b = sineWave(1000,2000,20);
auto start1 = std::chrono::high_resolution_clock::now();
auto d = waveAdd(a,b);
auto end1 = std::chrono::high_resolution_clock::now();
auto start2 = std::chrono::high_resolution_clock::now();
auto c = waveOperation(a,b,[] (i16 a, i16 b) { return (a+b); } );
auto end2 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(end1-start1);
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2-start2);
std::cout << "+ operator: " << duration1.count() << std::endl;
std::cout << "lambda: " << duration2.count() << std::endl;
}
有没有一种方法可以解决这个问题,或者最好只创建一个均衡长度辅助函数,然后复制粘贴并更改运算符?
我确实在 cpp.sh 中运行了它,而不是在我的机器上运行,但我认为这对所需的时间没有太大影响。
有没有一种方法可以解决这个问题,或者最好只创建一个均衡长度辅助函数,然后复制粘贴并更改运算符?
首先,了解
std::function
会带来运行时性能成本。 它的类型擦除不是免费的!
其次,您的 lambda 函数将编译时信息移至运行时。 编译器可以优化多个添加,但优化对任意
std::function::operator()
的多个调用会困难得多。
如果您在编译时知道想要什么 lambda,请将其作为模板参数传递!
template<auto operation>
std::vector<i16> waveOperation(std::vector<i16>& wave1, std::vector<i16>& wave2){
if(wave1.size() > wave2.size()){
wave1.resize(wave2.size());
}
else if(wave2.size() > wave1.size()){
wave2.resize(wave1.size());
}
std::vector<i16> final(wave1.size());
for(size_t i = 0;i<wave1.size();i++){
final[i] = operation(wave1[i],wave2[i]);
}
return final;
}