我是c ++的新手。
在每一帧中,我想用不同实例的数据填充矢量并按特定顺序处理这些数据,然后冲洗并重复。这个向量将相当大(可能有800多个元素),
我的问题是:
清除矢量是否比删除它更快,并且每帧都制作一个新的(适当大小以避免分配)?
PS:正在处理的数据是动态的,因此我为什么每帧需要一个干净的状态。
答案 0 :(得分:3)
你应该期望v.clear()
比} {vector<T> v; v.reserve(old_size);
更快(两个大括号通常划分相同的循环体),这只是因为它做了后者工作的一部分。两者都运行析构函数(如果有的话)并设置(后面的内部指针)end
到begin
,但后者也释放和(重新)分配内存,以及包含更多的指针赋值。 (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秒的时间,你无法回来。