microsoft / microsoft/STL

<string>: Fast path for SSO string constructions should be optimized

Open
#472 12 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

performance
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.