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

Optimize P3142R0 Printing Blank Lines With println() #4630

Closed
StephanTLavavej opened this issue Apr 25, 2024 · 0 comments · Fixed by #4672
Closed

Optimize P3142R0 Printing Blank Lines With println() #4630

StephanTLavavej opened this issue Apr 25, 2024 · 0 comments · Fixed by #4672
Labels
fixed Something works now, yay! performance Must go faster

Comments

@StephanTLavavej
Copy link
Member

For followup after #4611 implementing #4524 is merged.

This PR is implementing the Standard's "Effects equivalent to" wording which is simple and unquestionably correct.

However, blank-line println() is likely to be a popular function to call, and it appears that it goes through a general codepath that does a lot of work:

STL/stl/inc/print

Lines 97 to 117 in 0515a05

template <class... _Types>
void _Print_impl(
const _Add_newline _Add_nl, FILE* const _Stream, const format_string<_Types...> _Fmt, _Types&&... _Args) {
constexpr bool _Has_format_args = sizeof...(_Types) > 0;
if constexpr (_Has_format_args) {
if constexpr (_STD _Is_ordinary_literal_encoding_utf8()) {
_STD _Vprint_unicode_impl(_Add_nl, _Stream, _Fmt.get(), _STD make_format_args(_Args...));
} else {
_STD _Vprint_nonunicode_impl(_Add_nl, _Stream, _Fmt.get(), _STD make_format_args(_Args...));
}
} else {
const string _Unescaped_str{_Unescape_braces(_Add_nl, _Fmt.get())};
if constexpr (_STD _Is_ordinary_literal_encoding_utf8()) {
_STD _Print_noformat_unicode(_Stream, _Unescaped_str);
} else {
_STD _Print_noformat_nonunicode(_Stream, _Unescaped_str);
}
}
}

The optimizer is unlikely to see all the way through this.

From a brief glance, it appears that we could provide the newline as a string_view, bypassing the construction of a string _Unescaped_str:

STL/stl/inc/print

Lines 111 to 115 in 0515a05

if constexpr (_STD _Is_ordinary_literal_encoding_utf8()) {
_STD _Print_noformat_unicode(_Stream, _Unescaped_str);
} else {
_STD _Print_noformat_nonunicode(_Stream, _Unescaped_str);
}

However, it is unclear to me whether we could further optimize this (without spending tons of complicated code). In particular, because we know that "\n" doesn't contain any exotic characters, could we simply call _Print_noformat_nonunicode?

For <ostream>, I believe that less thought is necessary:

STL/stl/inc/ostream

Lines 1246 to 1263 in 0515a05

template <class... _Types>
void _Print_impl(const _Add_newline _Add_nl, ostream& _Ostr, const format_string<_Types...> _Fmt, _Types&&... _Args) {
constexpr bool _Has_format_args = sizeof...(_Types) > 0;
// This is intentionally kept outside of the try/catch block in _Print_noformat_*()
// (see N4950 [ostream.formatted.print]/3.2).
if constexpr (_Has_format_args) {
if constexpr (_STD _Is_ordinary_literal_encoding_utf8()) {
_STD _Vprint_unicode_impl(_Add_nl, _Ostr, _Fmt.get(), _STD make_format_args(_Args...));
} else {
_STD _Vprint_nonunicode_impl(_Add_nl, _Ostr, _Fmt.get(), _STD make_format_args(_Args...));
}
} else {
const string _Unescaped_str{_Unescape_braces(_Add_nl, _Fmt.get())};
_STD _Print_noformat(_Ostr, _Unescaped_str);
}
}

_STD _Print_noformat(_Ostr, _Unescaped_str) eventually switches between Unicode and non-Unicode, but it has to construct ostream::sentry machinery first, so it wouldn't be worth digging any deeper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed Something works now, yay! performance Must go faster
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant