
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.