查找高于阈值的值非常慢

时间:2014-09-22 20:08:46

标签: c++ vector

我有代码需要找到激光器被射击的时间点。激光在数据集上由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秒,我想知道是否有更快的方法。

1 个答案:

答案 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跳过的尺寸合适(太小意味着搜索太多,但太大而且您可能会丢失有效数据)

您也可以像评论者建议的那样同时执行此操作。您可以将搜索空间拆分为多个部分,并为每个部分生成一个线程。