Skip to content

<format>: Code bloat when using different iterator types #1835

@vitaut

Description

@vitaut

Describe the bug

std::format and std::format_to are missing the code bloat prevention mechanism present in {fmt} and noted in the standard:

For a given type charT, implementations are encouraged to provide a single instantiation of basic_­format_­context for appending to basic_­string, vector, or any other container with contiguous storage by wrapping those in temporary objects with a uniform interface (such as a span) and polymorphic reallocation.

Without it using different iterator types results in substantial code bloat. It can also have negative performance implications although those are difficult to measure.

In {fmt} this is implemented using an internal buffer that "erases" iterator types.

Command-line test case

C:\Temp>type format-one.cc
#include <format>

std::string foo() {
  return std::format("{}", 42);
}

int main() {
  foo();
}

C:\Temp>cl /std:c++latest /EHsc /I STL/stl/inc /O2 format-one.cc
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.29917 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.

format-one.cc
Microsoft (R) Incremental Linker Version 14.29.29917.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:format-one.exe
format-one.obj

C:\Temp>type format-two.cc
#include <format>
#include <vector>

std::string f() {
  return std::format("{}", 42);
}

std::vector<char> g() {
  std::vector<char> v;
  std::format_to(std::back_inserter(v), "{}", 42);
  return v;
}

int main() {
  f();
  g();
}

C:\Temp>cl /std:c++latest /EHsc /I STL/stl/inc /O2 format-two.cc
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.29917 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.

format-two.cc
Microsoft (R) Incremental Linker Version 14.29.29917.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:format-two.exe
format-two.obj

C:\Temp>dir
14.04.2021  07:24           371 712 format-one.exe
14.04.2021  07:26           401 408 format-two.exe

Expected behavior

There should be a small difference between two executable sizes. Currently using a new iterator type results in ~30k binary size increase. For comparison, replacing std::format and std::format_to in the above test files with their {fmt}'s counterparts results in ~2k increase.

STL version

4d7d4f1

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixedSomething works now, yay!formatC++20/23 formatperformanceMust go faster

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions