<string>: Fast path for SSO string constructions should be optimized
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
As reported by @miscco it's possible we might want to factor out reallocating cases in string constructors just like we did for all mutating operations in Visual Studio 2017 15.3: https://github.com/microsoft/STL/pull/467#issuecomment-579134473
Any changes in support of this item need performance tests characterizing any improvements or regressions for both small and large string sizes.
C:\Users\bion\Desktop>type demo.cpp
#include <string>
void example(void* p, std::string const& s) {
::new(p) std::string(s);
}
C:\Users\bion\Desktop>cl /EHsc /W4 /WX /O2 /c /std:c++latest /FA /nologo .\demo.cpp
demo.cpp
results in (after I strip file and line markers and annotate):
; Function compile flags: /Ogtpy
; COMDAT ?example@@YAXPAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
_TEXT SEGMENT
_p$ = 8 ; size = 4
_s$ = 12 ; size = 4
?example@@YAXPAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z PROC ; example, COMDAT
push ebx
mov ebx, DWORD PTR _s$[esp]
push ebp
push edi
mov edi, DWORD PTR _p$[esp+8]
mov DWORD PTR [edi+16], 0 ; Fill in the default string of zeros, 0 size, 16 capacity
mov DWORD PTR [edi+20], 0
cmp DWORD PTR [ebx+20], 16 ; 00000010H
mov ebp, DWORD PTR [ebx+16]
jb SHORT $LN13@example ; Test if the source string is in small mode
mov ebx, DWORD PTR [ebx]
$LN13@example:
cmp ebp, 16 ; 00000010H ; Redundant compare for small mode
jae SHORT $LN10@example
movups xmm0, XMMWORD PTR [ebx] ; Copy over the default zeroes and 16 with
movups XMMWORD PTR [edi], xmm0 ; contents of the copied string that was in SSO mode
mov DWORD PTR [edi+16], ebp
mov DWORD PTR [edi+20], 15 ; 0000000fH
pop edi
pop ebp
pop ebx
ret 0
$LN10@example:
push esi ; Allocate memory and fill in large mode string starts here;
mov esi, ebp ; factor in to separate function?
mov eax, 2147483647 ; 7fffffffH ; check max_size()
or esi, 15 ; 0000000fH
mov ecx, edi
cmp esi, eax
cmova esi, eax
lea eax, DWORD PTR [esi+1]
push eax
call ?allocate@?$allocator@D@std@@QAEPADI@Z ; std::allocator<char>::allocate
lea ecx, DWORD PTR [ebp+1]
mov DWORD PTR [edi], eax
push ecx
push ebx
push eax
call _memcpy
add esp, 12 ; 0000000cH
mov DWORD PTR [edi+16], ebp
mov DWORD PTR [edi+20], esi
pop esi
pop edi
pop ebp
pop ebx
ret 0
?example@@YAXPAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z ENDP ; example
_TEXT ENDS
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the issue's C++ reproduction and generated assembly, then read the referenced Visual Studio 2017 PR comment. Any implementation should be evaluated with performance tests covering both small and large string sizes. Done means the relevant SSO construction path is improved without introducing regressions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100