Algorithm 在最快的列表操作中,向量比列表快
我为我的游戏写了一个简单的a*算法: Navigation.hppAlgorithm 在最快的列表操作中,向量比列表快,algorithm,performance,list,c++11,vector,Algorithm,Performance,List,C++11,Vector,我为我的游戏写了一个简单的a*算法: Navigation.hpp #pragma once #include <SFML\Graphics.hpp> #include <algorithm> #include <iostream> #include <vector> #include <list> #include <set> using namespace std; class Field; //Compare
#pragma once
#include <SFML\Graphics.hpp>
#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
#include <set>
using namespace std;
class Field;
//Comparer using by set to allow priority
struct FieldComparer
{
bool operator()(const Field *, const Field *) const;
};
using FieldSet = set<Field*, FieldComparer>;
using FieldContainer = vector<Field*>; ///////////////////////////faster than list ?!
//Contains info about field, buildings builded on it and type of terrain
class Field
{
private:
sf::Vector2i mapPosition{ 0, 0 };
unsigned hCost{ 0 }; //to goal
unsigned gCost{ 0 }; //to start
Field * parent;
bool isWalkable { true };
bool isPathPart { false };
public:
void SetParent(Field&);
Field * GetParent() const;
unsigned GetFCost() const; //sum of hCost and gCost
unsigned GetHCost() const;
unsigned GetGCost() const;
bool IsWalkable() const;
bool IsPathPart() const;
void SetHCost(unsigned);
void SetGCost(unsigned);
void SetWalkable(bool);
void SetAsPartOfPath(bool);
sf::Vector2i GetMapPosition() const;
//compares positions
bool operator == (const Field& other);
Field(sf::Vector2i mapPosition, bool isWalkable)
: mapPosition(mapPosition), isWalkable(isWalkable) {}
};
//Contains fields and describes them
class Map
{
private:
sf::Vector2u mapSize;
Field *** fields; //two dimensional array of fields gives the fastest access
public:
sf::Vector2u GetMapSize() const;
Field *** GetFields();
Map(sf::Vector2u);
Map() {}
};
//Searching patch after giving a specified map
class PathFinder
{
private:
//Calculate score between two fields
unsigned CalcScore(Field&, Field&) const;
//Get neighbours of field in specified map
FieldContainer GetNeighbours(Field&, Map&) const;
public:
//Find path that have the lowest cost, from a to b in map
FieldContainer FindPath(Map&, Field&, Field&);
//Reconstruct path using pointers to parent
FieldContainer ReconstructPath(Field*, Field*) const;
};
导致ms释放
map size container time (average)
500x500 list 9,3
500x500 vector 7,4
1500x1500 list 23,9
1500x1500 vector 23,7
所以看起来向量比列表快,但为什么呢,因为列表在添加操作时应该更快
顺便问一下,这个算法快吗?如果没有,那么我可以改变什么来提高速度
谢谢。在有些情况下,列表比向量更快
显而易见的是,在集合的开头插入了很多项:
template <class T>
void build(T &t, int max) {
for (int i = 0; i < max; i++)
t.insert(t.begin(), i);
}
旁白:对于deque或vector,代码必须稍有不同,因为pos可能会因任何后续插入而无效,它们的第三个循环如下所示:
for (int i = 0; i < max; i++)
t.insert(t.begin() + max, i);
当然,这也不是这个主题的最后一个或唯一一个词——这在很大程度上还取决于你处理的项目有多大,因为大型项目至少通常复制速度相当慢
有趣的是:vector总是在末尾展开,但deque可以在末尾或开头展开,因此,尽管它并不理想,但它仍然明显比vector快
哦,还有一点:计时也可能因编译器/库的不同而有所不同。紧随其后的是gcc。使用VC++时,列表的速度差不多,vector的速度大约是vector的两倍,deque的速度要慢得多:
在与前面相同的系统上执行。有用的阅读:。2012年我的“本土化”主题演讲。从链接页面链接到一些非常好的细节。当然,列表速度较慢:它必须将每个元素存储在非连续内存中。如果可能,您应该使用deque或矢量。矢量在尝试展开时会出现性能问题,否则访问权限为O[1]。列表必须搜索列表的结尾,除非它有一个尾部指针,分配一个新节点,然后将新节点附加到列表中。是否优化发布版本?@RetiredInja ohh我忘记了发布模式,BWT.WOW 100MS-4ms,我不知道发布模式是如此强大……在STMC::DEQE中实现MSVC的LIbSTDCPP,所以这并不令人惊讶:@ Reito:不幸的是,他没有解释我认为足够详细的问题,尽管我承认,我也没有试图在这个答案中解释这一点,但主要是因为他一开始并没有问起德克。
map size container time (average)
500x500 list 9,3
500x500 vector 7,4
1500x1500 list 23,9
1500x1500 vector 23,7
template <class T>
void build(T &t, int max) {
for (int i = 0; i < max; i++)
t.insert(t.begin(), i);
}
template <class T>
void build2(T &t, int max) {
max = max / 3;
for (int i = 0; i < max; i++)
t.insert(t.begin(), i);
auto pos = t.begin();
for (int i = -max; i < 0; i++)
t.insert(t.begin(), i);
// Now `pos` refers to the middle of the collection, insert some there:
for (int i = 0; i < max; i++)
t.insert(pos, i);
}
for (int i = 0; i < max; i++)
t.insert(t.begin() + max, i);
List: 500 us
Deque: 3500 us
Vector: 6500 us
List: 526 us
Deque: 37478 us
Vector: 3657 us