将std :: strings插入到std :: map中

时间:2010-03-16 13:05:43

标签: c++ performance string map

我有一个程序可以逐行读取文件中的数据。我想将该行的一些子字符串复制到地图中,如下所示:

std::map< DWORD, std::string > my_map;
DWORD index;         // populated with some data
char buffer[ 1024 ]; // populated with some data
char* element_begin; // points to some location in buffer
char* element_end;   // points to some location in buffer > element_begin

my_map.insert( std::make_pair( index, std::string( element_begin, element_end ) ) );

std::map<>::insert()操作需要很长时间(文件解析时间加倍)。有没有办法让这个更便宜的操作?

谢谢, PaulH

编辑:更具体一点,我想知道我正在进行最少数量的复制操作,以便将文件中的数据传入地图。

8 个答案:

答案 0 :(得分:2)

你真的需要一张地图吗?就我在你的例子中看到的那样,你只想将索引存储为键值,正如我想的那样,只是为每次插入增加了一个值。您可以使用std::vector来完成此操作,这是最快的容器。只需使用push_back并使用at(index)访问该值。

答案 1 :(得分:2)

你可以尝试一些事情。数据结构和字符串本身的创建都涉及到开销。

  1. 是否需要map?您可以尝试使用std::tr1::unordered_map,看看是否有帮助。

  2. 查找需要多快?如果您可以使用O(n)查找时间,则可以尝试std::vector

  3. 您是否需要存储每个子字符串的副本?你可以只存储一个指针吗?

答案 2 :(得分:2)

也许您可以尝试其他版本的字符串构造函数:

string ( const char * s, size_t n );

如果你的字符串实现没有char *的特化,它将被强制遍历给定的范围并单独复制每个字符。在这种情况下,上面的构造函数可能更快(只是猜测)。

答案 3 :(得分:1)

稍微回答你的补充质询。尝试暂时将地图更改为字符串向量,然后将固定字符串值插入向量时计时:

vector <string> v;
string s( "foobar" );

your insert loop:
   v.push_back( s );

这应该会给你一个关于速度可能性的下限。

此外,您应该开启所有优化的时间(如果您还没有这样做)。这可能会给许多标准库操作带来惊人的差异。

答案 4 :(得分:0)

你正在存储字符串,但我猜你已经读过它们并将它们添加到地图中。这将导致副本。如果你在其中存储指向字符串的指针(字符串*而不是字符串)可能会更快。

答案 5 :(得分:0)

如果您的编译器无法优化插入中的冗余副本,您可以使用括号运算符直接分配到地图中:

my_map[index].assign(element_begin, element_end)

编辑:正如Neil指出的那样,如果可以插入重复的密钥,这将没有用。

答案 6 :(得分:0)

鉴于您需要将数据放入std::map<DWORD, std::string>然后,是的,您正在进行最少数量的复制操作以将数据导入地图。

答案 7 :(得分:0)

我相信你使用地图的大部分执行时间都是复制字符串。 std::map喜欢拥有自己的一切副本。因此,当您插入时,std::map会复制键和值。

很久以前,当处理器速度很慢且内存很小时,程序员会使用指向“大”数据项的指针并传递指针而不是每次都复制数据。指针是一个比字符串小得多的实体,需要较少的执行时间来复制。也许你应该在地图中存储指向字符串的指针:

#include <map>
#include <string>
#include "boost/shared_ptr.hpp"

typedef boost::shared_ptr<string>    Shared_Str_Ptr;

typedef std::map< DWORD, Shared_Str_Ptr> Map_Container;

//...
Map_Container my_map;
Shared_Str_Ptr p_str(new std::string("Hello"));
my_map[5] = p_str;

shared_ptr 会为您处理内存管理,因此在删除地图或其内容时无需担心。

另见Boost Smart Pointers