Deprecate folly::format

Summary:
`folly::format` is a problematic API because it returns a `Formatter` object that may store references to arguments as its comment warns:

```
 * Formatter class.
 *
 * Note that this class is tricky, as it keeps *references* to its lvalue
 * arguments (while it takes ownership of the temporaries), and it doesn't
 * copy the passed-in format string. Thankfully, you can't use this
 * directly, you have to use format(...) below.
```

This has negative safety and performance (encourages reuse of the same formatter) implications because contrary to what the comment says you can use the object directly since it's returned from `folly::format`. For example
```
auto f = folly::format(std::string("{}"), 42);
f.str();
```
is a UB with no compile-time diagnostic (only caught by ASAN).

It's also unnecessary because the `Formatter` object is usually converted to string straight away via `str()` or written to an output stream. Reusing the formatter doesn't make much sense either because the expensive part is formatting, not capturing arguments.

This diff deprecates `folly::format` suggesting `fmt::format` as a potential replacement. `fmt::format` doesn't have the above problem because arguments are always in scope. It also has the following advantages:

* Better compile times.
* Compile-time format string checks.
* Compatibility with C++20 `std::format`.
* Better performance, particularly with format string compilation which eliminates format string processing overhead altogether.
* Smaller binary footprint.

Also remove `folly::writeTo` which is no longer used and the `format_nested_fbstrings` benchmark which is identical to `format_nested_strings` since there is no `fbstr()` any more.

Reviewed By: yfeldblum

Differential Revision: D26391489

fbshipit-source-id: f0309e78db0eb6d8c22b426d4cc333a17c53f73e
This commit is contained in:
Victor Zverovich 2021-02-27 07:00:50 -08:00 committed by Facebook GitHub Bot
parent 3e0c5df020
commit f3feef687f
3 changed files with 10 additions and 9 deletions

View File

@ -10,6 +10,7 @@
#include "eden/fs/fuse/FuseChannel.h"
#include <boost/cast.hpp>
#include <fmt/core.h>
#include <folly/futures/Future.h>
#include <folly/logging/xlog.h>
#include <folly/system/ThreadName.h>
@ -546,7 +547,7 @@ std::string capsFlagsToLabel(uint32_t flags) {
if (flags == 0) {
return str;
}
return folly::format("{} unknown:0x{:x}", str, flags).str();
return fmt::format("{} unknown:0x{:x}", str, flags);
}
void sigusr2Handler(int /* signum */) {

View File

@ -17,6 +17,7 @@
#include <sstream>
#include <fb303/ServiceData.h>
#include <fmt/core.h>
#include <folly/Exception.h>
#include <folly/FileUtil.h>
#include <folly/SocketAddress.h>
@ -459,13 +460,12 @@ void EdenServer::ProgressManager::printProgresses(
content += folly::to<std::string>("Remounting ", it.mountPath, "\n");
printedFinished++;
} else {
content += folly::format(
"[{:21}] {:>3}%: fsck on {}{}",
std::string(it.fsckPercentComplete * 2, '=') + ">",
it.fsckPercentComplete * 10,
it.localDir,
"\n")
.str();
content += fmt::format(
"[{:21}] {:>3}%: fsck on {}{}",
std::string(it.fsckPercentComplete * 2, '=') + ">",
it.fsckPercentComplete * 10,
it.localDir,
"\n");
printedInProgress++;
}
totalLinesPrinted++;

View File

@ -218,7 +218,7 @@ class ThriftLogHelper {
~ThriftLogHelper() {
// Logging completion time for the request
// The line number points to where the object was originally created
TLOG(itcLogger_, level_, itcFileName_, itcLineNumber_) << folly::format(
TLOG(itcLogger_, level_, itcFileName_, itcLineNumber_) << folly::sformat(
"{}() took {:,} " EDEN_MICRO,
itcFunctionName_,
itcTimer_.elapsed().count());