$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [utility] new auto_buffer class --- RFC
From: Peter Dimov (pdimov_at_[hidden])
Date: 2009-03-03 12:15:22
Thorsten Ottosen:
> Christopher Jefferson skrev:
>>
>> On 2 Mar 2009, at 21:32, Thorsten Ottosen wrote:
>
>>> So did I in a real-time ray-tracing application. The difference was a 
>>> deal-breaker.
>>>
>>
>> Interesting, I wouldn't have expected to get such a big difference. I 
>> certainly have no trouble with a push_back_unchecked(), but think 
>> push_back() should do what it does in vector and friends.
>
> Right.
The reason for the apparent discrepancy is probably because Thorsten is 
comparing Dinkumware's vector::push_back against his unchecked 
auto_buffer::push_back, and erroneously attributing the difference in 
performance to the fact that push_back is not inlined (false; push_back 
itself is easily inlined by all compilers I know of) and to the presence of 
the capacity check.
In fact, the problem lies in the Dinkumware implementation of push_back, not 
in the interface requirements. Here's the older version (VC6):
 void push_back(const _Ty& _X)
  {insert(end(), _X); }
Why this underperforms should be obvious.
Here's the more recent version (VC7.1-9.0):
 void push_back(const _Ty& _Val)
  { // insert element at end
  if (size() < capacity())
   _Mylast = _Ufill(_Mylast, 1, _Val);
  else
   insert(end(), _Val);
  }
This is somewhat better, but still suboptimal, for two reasons. One, it 
diligently goes through Alloc::construct, using two nested function calls 
for that; two, size() and capacity() hide two divisions on sizeof(T).
Changing the implementation to check for _Mylast < _Myend and inlining the 
_Ufill call by hand improves the performance of vector<int>::push_back 
dramatically, and the unchecked version no longer has any significant 
advantage.