【问题标题】:Deque vs Queue Speed双端队列与队列速度
【发布时间】:2017-05-06 11:04:21
【问题描述】:

我正在解决 LeetCode (Here) 上的一个问题。当我完成问题时,我想出了:

class MovingAverage {
    std::deque<int> numsToAverage;
    int maxSize;
    int currentTotal;
public:
    /** Initialize your data structure here. */
    MovingAverage(int size) {
        maxSize = size;
        currentTotal = 0;
    }

    double next(int val) 
    {
        currentTotal += val;
        numsToAverage.push_back(val);

        if (numsToAverage.size() > maxSize)
        {
            currentTotal -= numsToAverage[0];
            numsToAverage.pop_front();
        }

        return (double)currentTotal / (double)numsToAverage.size();
    }
};

之后,我看到另一个解决方案与我的非常相似,但使用了队列。出于好奇,我只将双端队列换成了队列,然后我从第 18 个百分位(双端队列)跳到了第 56 个百分位(队列)。这是队列代码:

class MovingAverage {
    std::queue<int> numsToAverage;
    int maxSize;
    int currentTotal;
public:
    /** Initialize your data structure here. */
    MovingAverage(int size) {
        maxSize = size;
        currentTotal = 0;
    }

    double next(int val) 
    {
        currentTotal += val;
        numsToAverage.push(val);

        if (numsToAverage.size() > maxSize)
        {
            currentTotal -= numsToAverage.front();
            numsToAverage.pop();
        }

        return (double)currentTotal / (double)numsToAverage.size();
    }
};

我的问题具体是为什么?我检查了std::queue,它默认为双端队列!为什么仅仅因为它是一个队列它会更快?我唯一的猜测是它在某个地方缓存了该值?但同时,一个队列,默认是一个双端队列!插入/删除时间简直不能再好!

(旁注,我不考虑 size == 0 的情况,因为问题没有测试它。事实上,如果你把它交给 0,他们的代码会剧烈崩溃)

【问题讨论】:

  • 这就是测量之美。如果你的工具很糟糕,你的测量结果很糟糕。服务器提供半一致的结果,但偶尔会报告您有时更快或更慢。区别在于 100% 的服务器,仅此而已。
  • 如有疑问,请提供个人资料。

标签: c++ performance queue deque


【解决方案1】:

这是一个有根据的猜测:

  • 内存控制器具有预取“惯用手”,它奖励连续的、升序的内存访问,但按降序访问的速度较慢。

  • 因此,用作 FIFO 容器的双端队列有一个首选方向,即一侧推入另一侧弹出。

  • 很可能,您的双端队列代码使用了最不受欢迎的方向。但是队列实现已经优化,可以在最受青睐的方向使用底层双端队列。

  • 有一种简单的方法可以检验这个假设(假设这些是非保证的实现细节)。在你的双端队列代码中,切换push_back --&gt; push_frontpop_front --&gt; pop_back。如果假设正确,则双端队列代码的速度应该与队列实现一样快:-)

【讨论】:

    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 2018-07-02
    • 2016-01-19
    • 2015-05-01
    • 2020-04-19
    • 1970-01-01
    • 2013-03-10
    • 2023-03-28
    相关资源
    最近更新 更多