Post

string/ostringstream/vector的性能问题

其实最悲伤的一点是,我在之前的代码里大量用到了ostringstream,当时没有意识到这玩意其实在多线程下可能是有副作用的。

查资料的时候发现,ostringstream在构造的时候有加锁行为,在解释一些宽字符串(如汉字)的时候,依赖执行环境的本地化策略,一个可执行文件在运行前是无法确定这些转换策略的,所以ostringstream在构造的时候需要通过 std::locale()来获取本地化策略,std::locale()内其实是拷贝了全局的本地化策略,同时系统允许对本地化策略进行更改和重新设置。特别是使用ostringstream比较频繁的代码,可能会导致频繁的加锁和解锁操作,这个开销是很大的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
class ios_base {
public:
    locale
  getloc() const
  { return _M_ios_locale; }

  /**
    *  @brief  Locale access
    *  @return  A reference to the current locale.
    *
    *  Like getloc above, but returns a reference instead of
    *  generating a copy.
  */
  const locale&
  _M_getloc() const
  { return _M_ios_locale; }
protected:
    locale        _M_ios_locale;

}


const locale&
locale::operator=(const locale& __other) throw()
{
  __other._M_impl->_M_add_reference();
  _M_impl->_M_remove_reference();
  _M_impl = __other._M_impl;
  return *this;
}

locale::locale(const locale& __other) throw()
: _M_impl(__other._M_impl)
{ _M_impl->_M_add_reference(); }

locale::~locale() throw()
{ _M_impl->_M_remove_reference(); }

 class locale::_Impl
  {
    ...
    void
    _M_add_reference() throw()
    { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }

    void
    _M_remove_reference() throw()
    {
      // Be race-detector-friendly.  For more info see bits/c++config.
      _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
      if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
    {
          _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
      __try
        { delete this; }
      __catch(...)
        { }
    }
    }
  }

string的一些问题

  1. string的resize会call一次memset做初始化,如果你用这个做buffer,大概会多15%的cpu消耗
  2. string的data()跟vector的data()有一点点区别,vector的data()如果在vector是empty的时候有可能会返回nullptr

    多提一嘴,memcpy在遇到nullptr的时候会直接crash,所以在memcpy之前要做一次判断,哪怕size是0也要判断

REF

  1. C++ std::ostringstream 多线程性能问题探究
  2. ostringstream多线程下性能问题分析
This post is licensed under CC BY 4.0 by the author.

Trending Tags