Rico Mariani
1 min readMar 25, 2024

--

You benchmarked string copies and didn't observe a difference?

This is the code:

#include <string>

const char *q;

void assignStringPtr(const char *p)

{

q = p;

}

std::string s1;

void assignStdString(const std::string& s2)

{

s1 = s2;

}

This is the assembly:

assignStringPtr(char const*): # @assignStringPtr(char const*)

mov qword ptr [rip + q], rdi

ret

assignStdString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&): # @assignStdString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

mov rsi, rdi

lea rdi, [rip + s1[abi:cxx11]]

jmp std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@PLT # TAILCALL

_GLOBAL__sub_I_example.cpp: # @_GLOBAL__sub_I_example.cpp

mov rdi, qword ptr [rip + std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@GOTPCREL]

lea rax, [rip + s1[abi:cxx11]+16]

lea rsi, [rip + s1[abi:cxx11]]

lea rdx, [rip + __dso_handle]

mov qword ptr [rip + s1[abi:cxx11]], rax

mov qword ptr [rip + s1[abi:cxx11]+8], 0

mov byte ptr [rip + s1[abi:cxx11]+16], 0

jmp __cxa_atexit@PLT # TAILCALL

q:

.quad 0

s1[abi:cxx11]:

.zero 32

I'm not sure what kind of benchmark you did but there is no world where these are equivalent. One is O(1) the other is O(n).

I'm not sure what kind of benchmark you did but there is no world where these are equivalent. One is O(1) the other is O(n).

The O(1) "it's just a like a pointer assignment" is what people expect. The O(n) is what they are getting.

--

--

Rico Mariani
Rico Mariani

Written by Rico Mariani

I’m an Architect at Microsoft; I specialize in software performance engineering and programming tools.

Responses (1)