我使用gprof和报告来描述我的代码,大多数,如果不是所有前20个左右的东西都是关于vector
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
14.71 0.05 0.05 3870399 0.00 0.00 std::vector<bool, std::allocator<bool> >::size() const
11.76 0.09 0.04 10552897 0.00 0.00 std::_Bit_reference::_Bit_reference(unsigned long*, unsigned long)
11.76 0.13 0.04 7890323 0.00 0.00 std::_Bit_const_iterator::_Bit_const_iterator(std::_Bit_iterator const&)
5.88 0.15 0.02 10089215 0.00 0.00 std::_Bit_iterator::operator*() const
5.88 0.17 0.02 6083600 0.00 0.00 std::vector<bool, std::allocator<bool> >::operator[](unsigned int)
5.88 0.19 0.02 3912611 0.00 0.00 std::vector<bool, std::allocator<bool> >::end() const
5.88 0.21 0.02 std::istreambuf_iterator<char, std::char_traits<char> > std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::_M_extract_int<unsigned long long>(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, unsigned long long&) const
2.94 0.22 0.01 6523499 0.00 0.00 std::_Bit_reference::operator bool() const
2.94 0.23 0.01 3940406 0.00 0.00 std::vector<bool, std::allocator<bool> >::begin() const
2.94 0.24 0.01 2807828 0.00 0.00 std::_Bit_iterator::operator++()
2.94 0.25 0.01 146917 0.00 0.00 std::_Bit_iterator_base::_M_incr(int)
2.94 0.26 0.01 121706 0.00 0.00 std::__miter_base<unsigned long*, false>::__b(unsigned long*)
2.94 0.27 0.01 46008 0.00 0.00 std::_Bvector_base<std::allocator<bool> >::~_Bvector_base()
2.94 0.28 0.01 22596 0.00 0.00 std::_Bit_iterator std::__copy_move<false, false, std::random_access_iterator_tag>::__copy_m<std::_Bit_iterator, std::_Bit_iterator>(std::_Bit_iterator, std::_Bit_iterator, std::_Bit_iterator)
2.94 0.29 0.01 4525 0.00 0.05 integer::operator+(integer)
2.94 0.30 0.01 1382 0.01 0.01 void std::_Destroy<unsigned int*, unsigned int>(unsigned int*, unsigned int*, std::allocator<unsigned int>&)
2.94 0.31 0.01 std::string::size() const
2.94 0.32 0.01 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
2.94 0.33 0.01 std::locale::locale()
2.94 0.34 0.01 __dynamic_cast
这是一个好兆头,因为它意味着我的其余功能非常有效,或者从向量&lt; bool&gt;真的很慢?
使用gcc -std = c ++ 0x
进行编译答案 0 :(得分:8)
vector<bool>
不会存储bool
。它基本上是一个位域。你需要付出代价才能修改单个值。
如果需要关注运行时性能,请考虑使用vector<char>
或deque<bool>
。
答案 1 :(得分:2)
因为这意味着我的其余函数非常有效,或者从向量访问值真的很慢?
由于'慢'和'有效'是相对值,这实际上是一种无意义的区别。 解释报告的最客观方式是:
由于std :: vector'操作耗费了最长的时间,因此应该首先使代码更快。
请注意,std::vector<bool>
通常比std::vector<int>
慢一点,因为它不存储真实的bool
,而是存储一组位掩码(理想情况下,每个条目只需要一位) )。这节省了空间,但速度较慢。如果您需要更快,请尝试使用std::vector<int>
(或char
,..,取决于您的需要)。
我怀疑std::vector<bool>
可能会受到调试版本的影响很大,所以如果你没有这样做,请尝试一些优化标记(你总是应该进行分析)。
答案 2 :(得分:1)
vector<bool>
实际上是一个模板特化,其中每个bool
值都存储为单个位。但是,使用int
或仅使用“普通”bool
时,无法直接使用单个位。因此vector<bool>
中使用的算法与“普通”vector<>
非常不同,为了尽可能地保持vector
接口,它可能会返回操作位的代理对象你调用像operator[]
这样的函数。这可能会对gprof报告中的结果产生影响,具体取决于编译器的配置方式和相关代码。
答案 3 :(得分:1)
我会说它很臭,因为14.71%的时间花在了vector<bool>::size()
上!?!尺寸可能是给定的。
如果您事先知道尺寸,请尝试减少对size()的调用次数或使用固定大小的向量: bitset
编辑:
强制更改:g++ --std=c++0x -g -O3
(两个错字和优化标记,重新配置!);模板类大量使用内联,这反过来又可以进行大量的其他优化。加速的顺序很容易10倍
答案 4 :(得分:1)
它对您的计划有多大帮助?
除了vector<bool>
业务之外,它基本上什么也没告诉你。
您亲眼目睹了problems with gprof。
假设您知道某个函数具有较高的“自我时间”,这意味着程序计数器在其中被抽样了很多次,但它不是您编写或可以修改的函数。
你唯一能做的就是尽量减少调用它,或者尝试少调用调用它的例程,或者尝试少调用那个例程, 而你却试图猜测它在哪里。
gprof 试图通过猜测例程的包含时间是什么,调用它的次数以及调用图来帮助您。 如果没有递归,并且你只有十几个函数,并且你没有做任何I / O,这可能会有所帮助。
有一种略有不同的方法,体现在像Zoom这样的分析器中。 不是仅对程序计数器进行采样,而是对整个调用堆栈进行采样。 为什么?因为负责花费时间的代码行在那段时间内是在堆栈,只是要求被注意。
在挂钟时间内对调用堆栈进行采样的分析器,并告诉您大多数时间在堆栈中找到哪些代码行是最有效的。 更有效的是,如果你可以查看堆栈的各个样本,因为这也告诉你为什么要调用这些行,而不是多少,所以很容易判断你是否真的不需要它们。