STL string and go string

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

P.S. 这里不讨论COW(copy-on-write)和SSO(short-string-optimization)

STL string (gcc 4.9.3)

Through the source can be found, std::string inheritance and basic_string template, while basic_string contains only _alloc_hider _m_dataplus a non-static variable, and _alloc_hider contains only a pointer, So sizeof (string) might surprise you.

class basic_string{      //统计信息结构      struct _Rep_base      {        size_type               _M_length;    //长度        size_type               _M_capacity; //能力        _Atomic_word       _M_refcount; //引用计数      };      struct _Alloc_hider : _Alloc      {        _CharT* _M_p; // The actual data. //真实数据,就是个char*      };private:      ....      // Data Members (private):      // 可以看到string仅包含这一个数据字段      mutable _Alloc_hider      _M_dataplus;      ....};

About basic_string There is a trickery place: basic_string statistics are placed outside of data, obtained through an array [-1], the advantage is not to occupy basic_string memory, but also in O (1) time to obtain the structure has requested memory, Memory and reference count (for cow) have been used.

 _Rep* _M_rep() const _GLIBCXX_NOEXCEPT { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }

Get Real data

_CharT*_M_data() const _GLIBCXX_NOEXCEPT{ return  _M_dataplus._M_p; }

Graphic

                                    +---------> +-----------+ | |                                    _m_length| |           |           +-----------+                                    |                                    |_m_capacity|           |           +-----------+                                    |                                    |_m_refcount|           |                                    +-----------|                                    |                                    |                                    |  |                 _m_rep ()-+-------------+ | | _rep_base +----+ +-------------+basic_string--|                                    _m_dataplus +----+ +-------------+ |                                    |            |                                                 +---------------+----------> |1234567890.....| +---------------+    

Write a simple program verification under

// 禁止编译优化 输出调试信息// g++ -O0 -gdwarf-3 -o test test.cpp (gdb) p p$4 = (std::string *) 0x7fffffffe3d0(gdb) p (*((const std::string* )0x7fffffffe3d0)->_M_rep())._M_length$5 = 9(gdb) p (*((const std::string* )0x7fffffffe3d0)->_M_rep())._M_capacity$6 = 9(gdb) p (*((const std::string* )0x7fffffffe3d0)->_M_rep())._M_refcount$7 = 0

Memory allocations are raised when _m_p needs to be updated and _m_capacity is insufficient to hold all the data, while other operations, such as length (), iterator, operator[, etc., are combined _m_data () with _m_rep () A series of logical operations, here is not one by one repeat.

Go string

Take a look at the definition of Go string and the source code that *byte converted to string.
位于 src/runtime/string.go

String is the set of all strings of 8-bit bytes, conventionally but not//necessarily representing utf-8-encoded text. A string May is empty, but//not nil.        Values of String type is Immutable.type string string//the visible string consists of two parts: a pointer to the real address of the character, the length of the string, type stringstruct struct { STR unsafe. Pointer Len int}//Strong turn pointer func stringstructof (SP *string) *stringstruct {return (*stringstruct) (unsafe. Pointer (SP))}//by byte pointer stringfunc gostring (p *byte) string {l: = Findnull (p) if L = = 0 {RE Turn ""} s, B: = Rawstring (L) memmove (unsafe. Pointer (&b[0]), unsafe. Pointer (P), UIntPtr (L)) return s}//allocates memory, initializes func rawstring (size int) (s string, b []byte) {p: = MALLOCGC (UI Ntptr (size), nil, false) Stringstructof (&s). str = P Stringstructof (&s). Len = size * (*slice) (U Nsafe. Pointer (&b)) = slice{p, size, size} for {ms: = maxstring if uintptr (size) <= Ms || Atomic. Casuintptr ((*uintptr) (unsafe. Pointer (&maxstring)), MS, UIntPtr (size)) {return}}}

Let's look at a simple example to verify the following:

func main() {        s := "1234567890"        sLen := len(s)        fmt.Println(sLen)        s2 := s[3:]        sLen2 := len(s2)        fmt.Println(sLen2)}
(gdb) p s$1 = {  str = 0x4a5857 "12345678906103515625GOMAXPROCScasgstatuscomplex128float32nanfloat64nangcscandonegoroutine gp.stkbar=invalidptrowner diedplainErrorruntime: gschedtracesemacquireterminatedtracefree(tracegc()\nunknown pc"..., len = 10}(gdb) p s.str$2 = (    uint8 *) 0x4a5857 "12345678906103515625GOMAXPROCScasgstatuscomplex128float32nanfloat64nangcscandonegoroutine gp.stkbar=invalidptrowner diedplainErrorruntime: gschedtracesemacquireterminatedtracefree(tracegc()\nunknown pc"...//这里可见 s2.str - s.str == 3(gdb) p s2.str$3 = (    uint8 *) 0x4a585a "45678906103515625GOMAXPROCScasgstatuscomplex128float32nanfloat64nangcscandonegoroutine gp.stkbar=invalidptrowner diedplainErrorruntime: gschedtracesemacquireterminatedtracefree(tracegc()\nunknown pc (t"...(gdb) p &s$4 = (struct string *) 0xc420057ea8// 而s2与s的地址缺相差16 正好是stringStruct的大小(64位机器)(gdb) p &s2$5 = (struct string *) 0xc420057e98(gdb) p s2.len$6 = 7

The memory layout looks like this

                            +-----------------------+                            |12345678906103515....  |                            ++--+-------------------+                             ^  ^                             |  |s:                           |  |  +---+                      |  |  |str+----------------------+  |  +---+                         |  |len|  10                     |  +---+                         |                                |s2:                             |  +---+                         |  |str+-------------------------+  +---+  |len|  7  +---+

The elements in Go string are non-modifiable, and the append (+) operation also copies the contents of the two parameters into the new request memory, so there is a performance bottleneck for successive calls to the + operator, and a new object is generated by string and []byte] ( If necessary, it can be replaced by an unsafe pointer conversion). Of course the go provides a way to manipulate string methods set strings, such as join, and so on to some extent can optimize performance.

Summary comparison

string STL Go
Can write itself Is Whether
Length complexity O (1) O (1)
Allocating memory Is Whether

Reference documents

[1]. STL Source code Analysis--Houtie
[2]. Redis design and implementation--Huangjianhong
[3]. Go language Reading notes--rain marks

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.