vector 访问。

我使用gprof剖析了我的代码,并从报告中了解到,即使不是前20个左右,大多数(如果不是全部)都与向量有关
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
这是个好兆头吗,因为这意味着我的其余函数都非常有效,或者从vector 中访问值确实很慢? 我用gcc -std = c ++ 0x编译     
已邀请:
        
vector<bool>
不存储
bool
。它基本上是一个位域。您需要为修改单个值花些钱。 如果需要考虑运行时性能,请考虑使用
vector<char>
deque<bool>
。     
           因为这意味着我的其余函数相当有效,还是从向量访问值真的很慢? 由于\'slow \'和\'efficiency \'是相对值,因此这本质上是毫无意义的区别。 解释报告的最客观方法是: 由于std :: vector \的操作占用了最多的时间,因此这应该是使代码更快的起点。 请注意,ѭ5通常比ѭ6慢一些,因为它不存储真正的ѭ2,而是存储一组位掩码(即,理想情况下,每个条目只需要一位)。这样可以节省空间,但速度较慢。如果需要更快,请尝试使用
std::vector<int>
(或
char
,..,取决于您的需要)。 我怀疑ѭ5可能会因调试版本而遭受很大的损失,因此,如果您还没有这样做,请尝试一些优化标志(您始终应该进行概要分析)。     
        
vector<bool>
实际上是模板专门化,其中每个
bool
值都存储为一个位。但是,不可能像使用
int
或仅使用\“ normal \”
bool
一样直接使用单个位。因此,
vector<bool>
中使用的算法与\“ normal \”
vector<>
非常不同,并且为了尽可能多地保留
vector
接口,它可能会返回代理对象,当您调用
operator[]
之类的函数时,该对象会操纵这些位。这可能会对您的gprof报告中的结果有所贡献,具体取决于编译器的配置方式和相关代码。     
        我会说这很烂,因为您的时间中有14.71%花费在ѭ19上!!!大小可能是给定的。 如果您事先知道大小,请尝试减少对size()的调用次数或使用固定大小的向量:
bitset
阅读问题的更新后进行编辑: 强制更改:
g++ --std=c++0x -g -O3
(这是两个错字和优化标志,重新配置!);模板类大量使用内联,这反过来又带来了数不胜数的其他优化。加速的顺序很容易达到10倍     
        它说明了您的程序吗? 除了ѭ1业务以外,它基本上没有告诉您。 您直接看到了gprof的问题。 假设您知道某些函数具有很高的“自我时间”,这意味着程序计数器在其中采样了很多次,但这不是您编写或可以修改的函数。 您唯一可以做的就是尝试减少调用次数,或尝试减少调用它的例程,或者尝试减少调用该例程, 然后您就只能去猜测那是哪里了。 gprof还会通过猜测例程的包含时间,调用次数和调用图来帮助您。 如果没有递归,并且您只有十几个函数,并且您没有执行任何I / O,则这可能会有所帮助。 有一个稍微不同的方法,体现在诸如Zoom之类的探查器中。 不仅采样程序计数器,还采样整个调用堆栈。 为什么?因为负责这段时间的代码行是在这段时间内在堆栈上的,所以请注意一下。 探查器在挂钟时间对调用堆栈进行采样,并告诉您大多数时间在堆栈中找到哪些代码行是最有效的。 更有效的是,如果您可以查看堆栈中的各个样本,因为这还告诉您为什么调用这些行,而不仅仅是调用多少行,因此很容易判断您是否真的不需要它们。     

要回复问题请先登录注册