存储和检索这个的最佳方式..?

时间:2009-11-06 14:52:44

标签: c++ arrays maps storage vector

我一直在努力整夜,谈论地图,数组,向量和hash_maps已经充满了我的脑海。我现在很困惑。我在这里发布了上一个问题:C++ map really slow?

问题已得到解决,但似乎地图仍然不够快。我需要不断添加数据。在运行时添加ALOT数据。我现在一切都工作了,如果我每步添加1个数据(游戏中每帧)它工作正常。但是,一旦我一次做2,我看到性能下降。我调查了这个哈希的东西但是找不到很多东西。只是一个fyi,商品的数量可能永远不会超过2000〜左右。所以我猜它是相当小的缩放..

正如其他人所说,我试图存储的是: “具有id 101的对象具有值4用于设置1”或信息[101] [1] = 4; 除了我只是不断地使用不同的设置(第二个键)添加到系统中的越来越多的对象(不同的id,这是键值)。 - 我不知道阵列的大小是多少(这就是为什么我没有使用数组)。看着向量,但这让我感到困惑。 > _<

现在我有:

//declared as a class member
map<double,  map<int, double> > objIdMap;

//// lower down the page, in some function
map<int, double> objSettingsMap;
objSettingsMap[0] = value;
objSettingsMap[1] = value;
objSettingsMap[2] = value;
objSettingsMap[3] = value;
objIdMap[id] = objSettingsMap;
return(1);

或者它可能不是地图的?当地图如此频繁地使用时,地图执行缓慢是否正常? (ⅰhavnt包括它在上面的代码中,但对游戏的每一步与objIdMap一个id每个对象被访问,以检索其objSettingsMap值。虽然缓慢起伏只以上时超过每步骤一旦执行更多发生) ..

所以,是的,你们认为什么是保存这些数据并检索它的最佳方法?请提供示例:(谢谢

3 个答案:

答案 0 :(得分:2)

这可能很慢,因为每次你复制整个地图对象时都会这样做:

objIdMap[id] = objSettingsMap;

首先将空地图插入较大的地图,然后插入实际数据可能会更好。

map<int, double> objSettingsMap; 
objIdMap[id] = objSettingsMap; // insert the empty map so copying is fast

// Use a reference to the map so you don't have to keep looking it 
// up in the parent map
//
map<int, double>& mapref = objIdMap[id];
mapref[0] = value;
mapref[1] = value;
...etc..

编辑:你也说:

  

但是每场比赛的每一步   objIdMap中具有id的对象是   访问它以检索他们的   objSettingsMap

当一个对象访问它的objSettingsMap时,你确定它没有制作地图的副本吗? 另外,当你说数字开始为100000时,你的意思是你从100000开始计算?即key1 = 100000,key2 = 100001,key3 = 100002等。因为如果是这样,你只需使用vector并从每个键中减去100000。

答案 1 :(得分:1)

为什么不只是map<double, vector<double> >

答案 2 :(得分:0)

好像你真的不需要像这样嵌套地图。我建议定义一个“设置”结构,它包含您需要存储的设置数据。

struct Settings
{
    double setting1;
    double setting2;
    double settingN;
};

map<double,  Settings > objIdMap;

这样您就不必每次都添加整个地图。这应该有助于表现。 地图非常适合访问数据,但如果你做了很多,你应该使用数组或向量。如果你知道如何使用地图,那么矢量应该很容易上传。

vector<Settings> objects;

objects.push_back(Settings() );

objects[0].setting1 = 1234;

这当然可能不是矢量的实际应用,但它向您展示了如何添加对象并访问它们。使用向量时,添加一个导致内存重新分配的对象会有一个命中,但访问是立即的(除了需要缓存的内存)。

如果要删除对象并添加很多,我建议标记索引以便回收。您可以通过简单地保留另一个包含不再处于活动状态的对象索引的向量来完成此操作。添加检查列表以查看是否有要回收的索引。如果列表为空则推回另一个。这样,您可以最大限度地减少对象的删除和添加,这是最昂贵的操作。