/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 |