我有代码需要找到激光器被射击的时间点。激光在数据集上由500以上的DC表示,并且一次以3个激光器的体积,相当快速但不完全确定的时间间隙。
我现在正在使用的代码:
//std::vector<short>& laserData; this one comes from the function call, this is the definition
int count = 0;
for(unsigned int index = 0; index < laserData.size(); ++index) {
if(laserData.at(index) > 500) {
times.push_back(index);
count = (count + 1)%3;
if(count == 0) {
int dif1 = times.at(times.size()-1) - times.at(times.size()-2);
int dif2 = times.at(times.size()-1) - times.at(times.size()-3);
if(dif1 > 60000 || dif2 > 60000) {
times.erase(times.begin() + times.size() - 2);
times.erase(times.begin() + times.size() - 2);
count = 1;
}
}
switch(count) {
case 0: index += 90000;
default: index += 2000;
}
}
}
我不能完全确定所有3个激光脉冲总是会发生,如果它们不发生,则需要去除那些1或2个激光脉冲的全套。
数据集长度为130,000,000个样本,总共得到大约3300个激光脉冲,因此工作正常,它的速度很慢。解析该向量大约需要45秒,我想知道是否有更快的方法。
答案 0 :(得分:1)
首先:除非您打算将switch语句改为直通,否则请添加一个中断:
switch(count)
{
case 0:
index += 90000;
break;
default:
index += 2000;
}
确定。现在我们有一个潜在的错误,我们可以考虑加快您的代码。
要做的第一件事是尽可能多地消除矢量调整大小。 你说总共有大约3300个激光脉冲。让我们增加约10%的误差范围并提前调整脉冲矢量:
times.reserve(3600);
现在,矢量不需要多次调整大小。如果还有更多,我们应该只让矢量实现一次。
接下来,我们想要摆脱times.erase()
函数调用
为此,我们分别缓存三个最近的值,并且只有在它们被验证后才将它们推送到向量中:
const int pulse_interval = 2000;
const int burst_interval = 90000;
int cache[3];
times.reserve(3600);
for(unsigned int index = 0; index < laserData.size(); ++index)
{
if(laserData[index] > 500)
{
//this next if block acts as our guard clause
if (count > 0)
{
diff = index - cache[count-1];
if (diff > 60000)
{
count = 1;
cache[0]=index;
index+= pulse_interval;
continue;
// if gap between pulses is too big reset and start again, setting most recent value to first of next sequence.
}
}
//now we actually store data in the cache and if needed add to the vector. No invalid data (not part of a three burst set) should reach here due to guard
cache[count]=index;
if (count == 2)
{
for (int i=0; i<3; i++)
{times.push_back(cache[i]);}
count = 0;
index += burst_interval;
}
else
{
count++;
index += pulse_interval;
}
//updating count at the end is easier to follow
//goes to 0 after 3rd pulse detected
}
}
这会删除带有无效数据的矢量访问,并且应该加速代码,就像这里的快速回答一样。
编辑:添加到索引跳过参数中。如果我弄错了逻辑,请告诉我。在这种情况下,不需要开关,因为逻辑可以封装在算法的现有逻辑中。
如果无法启用优化,则可以尝试展开push_back
循环。缓存阵列可以缩减为两个单元格,index
的存储可以移动到else
(第三个值只有push_back(index);
这会消除每次发现完整突发时的循环开销和一个分配。您的编译器会正常处理此问题。
如果仍然很慢。那你需要剖析。确保您的index
跳过的尺寸合适(太小意味着搜索太多,但太大而且您可能会丢失有效数据)
您也可以像评论者建议的那样同时执行此操作。您可以将搜索空间拆分为多个部分,并为每个部分生成一个线程。