我有一个性能敏感的应用程序,其代码类似于
for each record r
processRecord(r)
然后
processRecord( record r )
{
for each field in record r
processField (f)
}
当我们的应用程序启动时,它使用xml文件填充地图。让我们称之为M.地图是字符串和结构。其中strung是xml标记中的名称,结构由xml中的所有其他元素组成。
processField中每个字段的处理是一个很长的操作,我们需要上面的映射M的帮助来找到map中指定的属性并相应地处理字段。
我们拥有来自外部的大量数据,当我进行分析时,我发现在地图M上执行查找操作所花费的最长时间。
地图由xml中的字段组成,我可以放心地说地图的大小在50到200之间。
发送到我们应用程序的记录数量是每秒300个&每条记录都有与地图大小相同的字段。
在网上快速搜索表明,人们可以尝试使用unordered_map,但它在我的旧c ++编译器中不可用,因为我们还没有转移到C ++ 11,这是我无法控制的。同样在网上似乎对于像我的地图和unordered_map这样的较小集合也会给出类似的结果。
我们不关心地图创建是否需要时间作为一次性活动但是想要快速查找()s 因此,当我进行分析时,我发现在地图M上执行查找操作所花费的最长时间,我希望减少它。有什么建议吗?
我的探查器提到我的地图的具体api是(前2)
1) std::_Select1st<std::pair<int const, int> >::operator() (this=0x7f1a679eb1bf, __x=...) at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_function.h:489
and
2) #0 0x00000000005e3d7f in std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::~_Rb_tree (this=0x7f1a679ebf72, __in_chrg=<value optimized out>) at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:613
#1 0x00000000005e3d42 in std::set<int, std::less<int>, std::allocator<int> >::~set (this=0x7f1a679eb5d0, __in_chrg=<value optimized out>) at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_set.h:88
修改 我能够使用下面的建议改进性能:)。我测试了一小组随机数据。我对std:map的cpu使用率在std :: _ Rb_tree *中是~12.24%。使用boost :: unordered_map我在boost :: unordered_detail :: *中只得到4.34%所以这意味着我有~7%的cpu用于其他活动。
答案 0 :(得分:0)
回答我自己的问题,因为其他用户也可能会遇到此问题。 我能够使用我的问题的评论部分中的建议来改善性能。
@RetiredNinja 建议我使用boost unordered map
要理解我提到的link。该网站的相关文字是这样的 有序地图通常是在有序树的基础上实现的,例如STL案例中的红黑树。树操作相对昂贵,但树使用非常少的存储。 无序地图通常实现为哈希表;较新的STL实现也提供了这样的地图。哈希表非常快,但是有一些存储开销,只能在它们效率低下之前增长到一定数量的节点。
由于我对查找调用更加困扰,插入只会发生一次我想到尝试无序地图 boost :: unordered_map 。空间限制对我来说并不重要,因为我的地图尺寸很小(最多200个元素)。
我测试了一小组随机数据。我运行了我的性能测试,以确定哪个api现在更多地消耗cpu周期。使用std:map时我的cpu使用率在std :: _ Rb_tree *调用中加起来大约为12.24%..使用boost :: unordered_map我在boost :: unordered_detail :: *调用时只得到4.34%。所以这意味着我为其他活动节省了大约7%的cpu。
如果其他人可以给我更多的方法,我仍会等待,但现在这对我有很大的帮助。