簡體   English   中英

小字符串優化(調試與發布模式)

[英]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


我的問題很簡單:為什么DebugRelease模式之間有這種區別?

在調試模式下,小字符串優化仍然存在。 如果我們創建一個更大的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構建來禁用迭代器調試(但隨后它將對所有容器禁用,對於vectormap等也是如此)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM