【问题标题】:bottleneck c++ sort functionWi-Fi signals瓶颈 C++ 排序函数Wi-Fi 信号
【发布时间】:2017-07-19 12:13:44
【问题描述】:

目前我正在制作一个程序,在该程序中我使用 RSSI 估计 WiFi 设备坐标。程序存在瓶颈。

我尝试将字符串比较替换为其他函数。那没有

完整功能:

std::list<std::list<wSignal*>> SignalGrouper::groupByMac (std::list<wSignal*> signals)
{
    std::list<std::list<wSignal*>> groupedSignals;
    std::list<wSignal*> doneSignals;
    for (std::list<wSignal*>::iterator it1=signals.begin(); it1 != signals.end(); ++it1) //take first signal
    {
        if(DoesSignalExist(doneSignals, *it1) == false) //check if signal is already been grouped
        {
            std::list<wSignal*> group;
            for (std::list<wSignal*>::iterator it2=signals.begin(); it2 != signals.end(); ++it2)
            {
                if(DoesSignalExist(doneSignals, *it2) == false)
                {
                    if(boost::iequals((*it2)->MAC, (*it1)->MAC))
                    {
                        group.push_back(*it2);
                        doneSignals.push_back(*it2);
                    }
                }
            }
            groupedSignals.push_back(group);
        }
    }
    return groupedSignals;
}

【问题讨论】:

  • 您如何确定它是瓶颈?是堆栈跟踪的统计抽样吗?因为如果你有数十亿的字符串,自然代码会花很多时间在(*it2)-&gt;MAC == (*it1)-&gt;MAC。没有比专用功能更高效的了。
  • 您通过副本传递您的列表?!
  • 您可以通过 MAC sort 您的信号,将算法复杂度从 O(N²) 降低到 O(N logN)
  • 链表是最被高估的数据结构。
  • 由于MAC地址正好是6个字节,你可以使用uint64_t来存储和比较项目。

标签: c++ sorting linked-list lag


【解决方案1】:

必须是要返回的 std::list 吗?否则,您可以像这样使用 std::map 来减少迭代步骤:

std::map<MAC, std::list<wSignal*>> SignalGrouper::groupByMac (std::list<wSignal*> signals)
{
    std::map<MAC, std::list<wSignal*>> groupedSignals;
    for (std::list<wSignal*>::iterator it1 = signals.begin(); it1 != signals.end(); ++it1) //take first signal
    {
        std::map<MAC, std::list<wSignal*>>::iterator it2 = groupedSignals.find((*it1)->MAC);
        if(it2 != groupedSignals.end()) {
            it->second.push_back(*it1);
        } else {
            groupedSignals[(*it1)->MAC] = (*it1);
        }
    }
    return groupedSignals;
}

未经测试,但应该可以这样工作。

【讨论】:

  • for (auto* signal : signals) { groupedSignals[signal-&gt;MAC].push_back(signal); }
【解决方案2】:

我也怀疑字符串比较是否是真正的问题。但如果您坚持使用更快的方式比较 MAC 字符串,您可以尝试反向比较,因为前缀 (OUI) 是由 IEEE 提供给供应商的,因此对于同一供应商来说总是相同的。

【讨论】:

    【解决方案3】:

    试试

    #include <boost/algorithm/string.hpp>
    
    boost::equals((*it2)->MAC, (*it2)->MAC);
    

    或用于不区分大小写的比较

    boost::iequals((*it2)->MAC, (*it2)->MAC);
    

    【讨论】:

    • 像这样改进字符串比较没有用。有什么建议瓶颈可能在哪里?在这个函数中,我试图将 std::list 排序为较小的 std::list ,其中信号都具有相同的 MAC。我想要一个列表中包含的那些较小的列表: std::list<:list>>
    【解决方案4】:

    不,没有更快的方法来直接比较两个任意字符串。内置方法是最快的方法。

    与您当前的 O(n^2) 算法不同,您可以先在O(n log n) 中对 MAC 列表进行排序(例如,通过将它们放入 std::vector 然后使用 std::sort),然后只需对排序的 MAC 列表运行一次迭代向量将相邻的相等元素聚合成一个组列表(即O(n),整体复杂度为O(n log n))。

    由于要分组的 MAC 数量众多,因此与尝试优化单行相比,这样的算法复杂性变化可能会导致更大的性能提升。

    【讨论】:

    • 当向量需要按结构成员排序时,如何对它进行排序? (wSignal)
    • @RikSmits:你只需要一个比较函数或operator &lt;,就像这样:stackoverflow.com/a/1380496/8051589
    猜你喜欢
    • 2023-03-20
    • 2013-02-02
    • 1970-01-01
    • 2023-03-20
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多