[英]Small String Optimisation (Debug vs Release mode)
我一直在使用以下示例腳本檢查小字符串優化(在 MSVC 2019 中):
#include <string>
void* operator new(size_t size)
{
std::printf("global op new called, size = %zu\n", size);
void* ptr = std::malloc(size);
if (ptr)
return ptr;
else
throw std::bad_alloc{};
}
int main()
{
std::string test = "small value";
return 0;
}
請注意,我從https://en.cppreference.com/w/cpp/memory/new/operator_new 獲取了void* operator new(size_t size)
。
在Release模式下,優化按預期工作(即new
不會被調用),但在Debug模式下,腳本實際上打印global op new called, size = 16
。 深入研究后,這似乎是由於標題xmemory
此代碼段造成的:
#if _ITERATOR_DEBUG_LEVEL == 0
#define _GET_PROXY_ALLOCATOR(_Alty, _Al) _Fake_allocator()
template <class _Alloc>
using _Container_proxy_ptr = _Fake_proxy_ptr_impl;
#else // _ITERATOR_DEBUG_LEVEL == 0
#define _GET_PROXY_ALLOCATOR(_Alty, _Al) static_cast<_Rebind_alloc_t<_Alty, _Container_proxy>>(_Al)
template <class _Alloc>
using _Container_proxy_ptr = _Container_proxy_ptr12<_Rebind_alloc_t<_Alloc, _Container_proxy>>;
#endif // _ITERATOR_DEBUG_LEVEL == 0
我們可以看到在Release模式下(即_ITERATOR_DEBUG_LEVEL == 0
)我們使用_Fake_proxy_ptr_impl
,而在Debug模式下我們使用_Container_proxy_ptr12
,它使用new
。
我的問題很簡單:為什么Debug和Release模式之間有這種區別?
在調試模式下,小字符串優化仍然存在。 如果我們創建一個更大的string
std::string test = "large value.large value.large value.large value.";
然后我們得到實際的string
分配
global op new called, size = 64
在 Debug 和 Release 版本中。
您正在觀察的是用於迭代器調試的容器代理的分配(從#if _ITERATOR_DEBUG_LEVEL
可以看出)
struct _Container_proxy { // store head of iterator chain and back pointer
您可以通過使用/D _ITERATOR_DEBUG_LEVEL=0
構建來禁用迭代器調試(但隨后它將對所有容器禁用,對於vector
、 map
等也是如此)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.