Skip to content

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

@StephanTLavavej

Description

@StephanTLavavej

@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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixedSomething works now, yay!formatC++20/23 formatthroughputMust compile faster

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions