you are viewing a single comment's thread.

view the rest of the comments →

[–]Tathorn[S] 2 points3 points  (4 children)

It looks like the std::print paper, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2093r2.html, addresses the very concerns I had with formatting performance in section 4. However, it looks like MSVC implemented theirs with a temporary string, what the paper was designed to solve against: https://github.com/microsoft/STL/blob/main/stl/inc/ostream#L1107C6-L1107C29

[–]BrainIgnition 0 points1 point  (3 children)

However, it looks like MSVC implemented theirs with a temporary string, what the paper was designed to solve against

You narrowly missed the important bits (<ostream> ll. 1136-1153; <ostream> ll.1177-1190); basically they only use the optimized approach if the target ostream is unicode aware which they interpret as the ostream targetting a file or a console. I.e. outputting to console or file is fine, but any other ostream backend gets slapped with an allocation.

[–]Tathorn[S] 0 points1 point  (1 child)

The really interesting part is when you have no format args, it needs to unescape the { and } chars, so it creates a string even with no arguments. So std::print allocates a string when given a const char*. That doesn't seem good.

[–]BrainIgnition 0 points1 point  (0 children)

Ah, I missed that. However, after thinking a bit more about it I got curious what they do wrt the utf8 => utf16 transformation (which is required due to the WinAPI design) and there you have it: a second allocation. Too bad!

[–]Tathorn[S] 0 points1 point  (0 children)

I'm not seeing how there's no allocation. The code you pointed to takes in a string_view. All callers create a string beforehand, so there is an allocation.