矢量:清除它与删除它

时间:2018-05-21 01:59:20

标签: c++

我是c ++的新手。

在每一帧中,我想用不同实例的数据填充矢量并按特定顺序处理这些数据,然后冲洗并重复。这个向量将相当大(可能有800多个元素),

我的问题是:

清除矢量是否比删除它更快,并且每帧都制作一个新的(适当大小以避免分配)?

PS:正在处理的数据是动态的,因此我为什么每帧需要一个干净的状态。

2 个答案:

答案 0 :(得分:3)

你应该期望v.clear()} {vector<T> v; v.reserve(old_size);更快(两个大括号通常划分相同的循环体),这只是因为它做了后者工作的一部分。两者都运行析构函数(如果有的话)并设置(后面的内部指针)endbegin,但后者也释放和(重新)分配内存,以及包含更多的指针赋值。 (clear不释放内存,因为它不是affect capacity。)

然而,希望无关紧要,特别是如果向量很大和/或构造/破坏元素是昂贵的:它在概念上优于限制向量的相关循环迭代的生命周期,而不是让它延伸到循环外部直到某个封闭块的(可能是远程的)末端。通过使用自定义分配器来保持存储更长时间,可以在不牺牲性能的情况下这样做,但这需要分配器的封闭块,并且通常很麻烦。

答案 1 :(得分:0)

将矢量调整到您认为框架所需的尺寸并保持size_t mCursor=0

插入时,递增mCursor++;什么时候你清楚&#39;对于下一帧,只需将其设置为mCursor=0

如果在帧期间避免调整矢量大小,则数据将在帧的持续时间内位于相同的存储位置。此外,如果您限制(mCursor >= vector.size),只需删除数据并记住丢弃的精灵数量。然后在帧之间调整矢量大小。

保留光标的最大计数器,以便您可以更新源以从较大的向量开始。但在某些时候,你可能想要删除精灵,特别是如果你用粒子重载它。

Perf代码:

// SpeedTestClearVector.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <time.h>
#include <vector>


namespace sf
{
    class Texture;
    struct IntRect { int rect[4]; };
    struct FloatRect { float rect[4]; };
    struct RenderTarget { };
    struct Vertex { float verts[3]; float uv[2]; };
    enum RenderStates {};
    typedef IntRect Color;

    class Sprite // : public Drawable, public Transformable
    {
    public:
        Sprite() {}
        explicit Sprite(const Texture& texture) {}
        Sprite(const Texture& texture, const IntRect& rectangle) {}
        void setTexture(const Texture& texture, bool resetRect = false) {}
        void setTextureRect(const IntRect& rectangle) {}
        void setColor(const Color& color) {}
        const Texture* getTexture() const {}
        const IntRect& getTextureRect() const {}
        const Color& getColor() const {}
        FloatRect getLocalBounds() const {}
        FloatRect getGlobalBounds() const {}

    private:
        virtual void draw(RenderTarget& target, RenderStates states) const {}
        void updatePositions() {}
        void updateTexCoords() {}

        Vertex         m_vertices[4]; ///< Vertices defining the sprite's geometry
        const Texture* m_texture;     ///< Texture of the sprite
        IntRect        m_textureRect; ///< Rectangle defining the area of the source texture to display
    };

} // namespace sf


int main()
{
    std::cout << "Hello World" << std::endl;

    const size_t reserve_size = 1024;
    const size_t iterations = 1000000;

    // Vector Clear
    {
        std::vector<sf::Sprite> spriteCache;
        spriteCache.reserve(reserve_size);

        time_t start_time = time(nullptr);

        for (size_t n = 0; n < iterations; ++n)
        {
            spriteCache.resize(reserve_size);
            spriteCache.clear();
        }

        auto total_time = difftime(time(nullptr), start_time);
        std::cout << "vector::clear() took " << total_time << " seconds of your life that you cannot have back." << std::endl;
    }
    // Output:
    // vector::clear() took 6 seconds of your life that you cannot have back.

    // Vector Cursor
    {
        std::vector<sf::Sprite> spriteCache;
        spriteCache.resize(reserve_size);
        size_t mCursor = 0;

        time_t start_time = time(nullptr);

        for (size_t n = 0; n < iterations; ++n)
        {
            spriteCache.resize(reserve_size); // does nothing, but included to be similar to previous test
            mCursor = reserve_size;
            mCursor = 0;
        }

        auto total_time = difftime(time(nullptr), start_time);
        std::cout << "Vector mCursor took " << total_time << " seconds of your life that you cannot have back." << std::endl;
    }
    // Output:
    // Vector mCursor took 0 seconds of your life that you cannot have back.


    // Vector "new" lol
    {
        time_t start_time = time(nullptr);

        for (size_t n = 0; n < iterations; ++n)
        {
            std::vector<sf::Sprite> spriteCache;
            spriteCache.resize(reserve_size); 
            spriteCache.clear();
        }

        auto total_time = difftime(time(nullptr), start_time);
        std::cout << "Vector 'new' took " << total_time << " seconds of your life that you cannot have back." << std::endl;
    }
    // Output:
    // Vector 'new' took 6 seconds of your life that you cannot have back.

    return 0;
}
  

vector :: clear()花了6秒的时间让你无法回来。

     

Vector mCursor花了你生命的0秒,你无法回来。

     

Vector&#39; new&#39;花了你6秒的时间,你无法回来。