Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/buffer/buffer_util.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/common/buffer/buffer_util.h"
2
3
#include <charconv>
4
#include <cstddef>
5
6
#include "source/common/common/macros.h"
7
8
namespace Envoy {
9
namespace Buffer {
10
11
0
void Util::serializeDouble(double number, Buffer::Instance& buffer) {
12
  // Converting a double to a string: who would think it would be so complex?
13
  // It's easy if you don't care about speed or accuracy :). Here we are measuring
14
  // the speed with test/server/admin/stats_handler_speed_test --benchmark_filter=BM_HistogramsJson
15
  // Here are some options:
16
  //   * absl::StrCat(number) -- fast (19ms on speed test) but loses precision (drops decimals).
17
  //   * absl::StrFormat("%.15g") -- works great but a bit slow (24ms on speed test)
18
  //   * `snprintf`(buf, sizeof(buf), "%.15g", ...) -- works but slow as molasses: 30ms.
19
  //   * fmt::format("{}") -- works great and is a little faster than absl::StrFormat: 21ms.
20
  //   * fmt::to_string -- works great and is a little faster than fmt::format: 19ms.
21
  //   * std::to_chars -- fast (16ms) and precise, but requires a few lines to
22
  //     generate the string_view, and does not work on all platforms yet.
23
  //
24
  // The accuracy is checked in buffer_util_test.
25
0
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 14000
26
  // This version is awkward, and doesn't work on all platforms used in Envoy CI
27
  // as of August 2023, but it is the fastest correct option on modern compilers.
28
0
  char buf[100];
29
0
  std::to_chars_result result = std::to_chars(buf, buf + sizeof(buf), number);
30
0
  ENVOY_BUG(result.ec == std::errc{}, std::make_error_code(result.ec).message());
31
0
  buffer.addFragments({absl::string_view(buf, result.ptr - buf)});
32
33
  // Note: there is room to speed this up further by serializing the number directly
34
  // into the buffer. However, buffer does not currently make it easy and fast
35
  // to get (say) 100 characters of raw buffer to serialize into.
36
#else
37
  // On older compilers, such as those found on Apple, and gcc, std::to_chars
38
  // does not work with 'double', so we revert to the next fastest correct
39
  // implementation.
40
  buffer.addFragments({fmt::to_string(number)});
41
#endif
42
0
}
43
44
} // namespace Buffer
45
} // namespace Envoy