Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<format>: inline overloads of vformat() are costly for throughput #2329

Closed
StephanTLavavej opened this issue Nov 10, 2021 · 0 comments · Fixed by #2331
Closed

<format>: inline overloads of vformat() are costly for throughput #2329

StephanTLavavej opened this issue Nov 10, 2021 · 0 comments · Fixed by #2331
Labels
fixed Something works now, yay! format C++20/23 format throughput Must compile faster

Comments

@StephanTLavavej
Copy link
Member

@xiangfan-ms reported (slightly edited for Markdown):

<format> contains 4 overloads of vformat. They will specialize lots of other templates. But unlike other functions in STL headers, they are non-template.

STL/stl/inc/format

Lines 2885 to 2911 in 178b840

_NODISCARD inline string vformat(const string_view _Fmt, const format_args _Args) {
string _Str;
_Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity());
_STD vformat_to(back_insert_iterator{_Str}, _Fmt, _Args);
return _Str;
}
_NODISCARD inline wstring vformat(const wstring_view _Fmt, const wformat_args _Args) {
wstring _Str;
_Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity());
_STD vformat_to(back_insert_iterator{_Str}, _Fmt, _Args);
return _Str;
}
_NODISCARD inline string vformat(const locale& _Loc, const string_view _Fmt, const format_args _Args) {
string _Str;
_Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity());
_STD vformat_to(back_insert_iterator{_Str}, _Loc, _Fmt, _Args);
return _Str;
}
_NODISCARD inline wstring vformat(const locale& _Loc, const wstring_view _Fmt, const wformat_args _Args) {
wstring _Str;
_Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity());
_STD vformat_to(back_insert_iterator{_Str}, _Loc, _Fmt, _Args);
return _Str;
}

It takes 0.83s to compile <format> and all its dependencies. But if I remove the definition of vformat, it only takes 0.62s.

Here are some data:

With definition Without definition
Overload resolution 0.185821s / 11218 0.075068s / 6024
Instantiate template specialization 0.161868s / 1333 0.079736s / 583
Specialize template 0.187945s / 10900 0.091789s / 7597
Parse default template argument 0.008578s / 691 0.004705s / 403

I believe that template <int = 0> should be sufficient to delay this throughput cost (i.e. unless and until vformat() is actually called), and that it should be unobservable because users are now forbidden from taking the addresses of Standard Library functions. We should probably have comments as to why we're doing this.

@xiangfan-ms replied:

The template <int = 0> trick seems to work (two phase will still try to bind the function call to std::vformat_to, but I think the function specialization isn't added to the list to be instantiated).

@StephanTLavavej StephanTLavavej added throughput Must compile faster format C++20/23 format labels Nov 10, 2021
@StephanTLavavej StephanTLavavej added the fixed Something works now, yay! label Nov 13, 2021
tylerbrawl added a commit to tylerbrawl/MSVC-STL that referenced this issue Jan 9, 2023
H-G-Hristov pushed a commit to H-G-Hristov/STL that referenced this issue Apr 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed Something works now, yay! format C++20/23 format throughput Must compile faster
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant