[libcxx-commits] [PATCH] D101752: Speedup to_string for integers using zero-copy.

Roman Koshelev via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sat May 8 04:44:15 PDT 2021


Roman-Koshelev updated this revision to Diff 343831.
Roman-Koshelev added a comment.

Updating D101752 <https://reviews.llvm.org/D101752>: Speedup to_string for integers using zero-copy.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101752/new/

https://reviews.llvm.org/D101752

Files:
  libcxx/src/string.cpp


Index: libcxx/src/string.cpp
===================================================================
--- libcxx/src/string.cpp
+++ libcxx/src/string.cpp
@@ -422,34 +422,48 @@
 #endif
 }
 
-template <typename S, typename V>
-S i_to_string(const V v)
+template <typename Ty>
+struct num_limits {
+    static constexpr int max_chars10 = numeric_limits<Ty>::digits10 + 1 + (is_signed<Ty>::value ? 1 : 0);
+};
+
+template <typename V>
+string i_to_string(const V v)
+{
+    string buf;
+    buf.resize(buf.capacity());
+    _LIBCPP_ASSERT(buf.size() >= num_limits<V>::max_chars10, "Capacity is too small");
+    const auto res = to_chars(buf.data(), buf.data() + buf.size(), v);
+    _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
+    buf.resize(res.ptr - buf.data());
+    return buf;
+}
+
+template <typename V>
+wstring i_to_wstring(const V v)
 {
-//  numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
-//  For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented),
-//  so we need +1 here.
-    constexpr size_t bufsize = numeric_limits<V>::digits10 + 2;  // +1 for minus, +1 for digits10
+    constexpr size_t bufsize = num_limits<V>::max_chars10;
     char buf[bufsize];
     const auto res = to_chars(buf, buf + bufsize, v);
     _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value");
-    return S(buf, res.ptr);
+    return wstring(buf, res.ptr);
 }
 
 }  // unnamed namespace
 
-string  to_string (int val)                { return i_to_string< string>(val); }
-string  to_string (long val)               { return i_to_string< string>(val); }
-string  to_string (long long val)          { return i_to_string< string>(val); }
-string  to_string (unsigned val)           { return i_to_string< string>(val); }
-string  to_string (unsigned long val)      { return i_to_string< string>(val); }
-string  to_string (unsigned long long val) { return i_to_string< string>(val); }
-
-wstring to_wstring(int val)                { return i_to_string<wstring>(val); }
-wstring to_wstring(long val)               { return i_to_string<wstring>(val); }
-wstring to_wstring(long long val)          { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned val)           { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned long val)      { return i_to_string<wstring>(val); }
-wstring to_wstring(unsigned long long val) { return i_to_string<wstring>(val); }
+string  to_string (int val)                { return i_to_string(val); }
+string  to_string (long val)               { return i_to_string(val); }
+string  to_string (long long val)          { return i_to_string(val); }
+string  to_string (unsigned val)           { return i_to_string(val); }
+string  to_string (unsigned long val)      { return i_to_string(val); }
+string  to_string (unsigned long long val) { return i_to_string(val); }
+
+wstring to_wstring(int val)                { return i_to_wstring(val); }
+wstring to_wstring(long val)               { return i_to_wstring(val); }
+wstring to_wstring(long long val)          { return i_to_wstring(val); }
+wstring to_wstring(unsigned val)           { return i_to_wstring(val); }
+wstring to_wstring(unsigned long val)      { return i_to_wstring(val); }
+wstring to_wstring(unsigned long long val) { return i_to_wstring(val); }
 
 
 string  to_string (float val)       { return as_string(snprintf,       initial_string< string>()(),   "%f", val); }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101752.343831.patch
Type: text/x-patch
Size: 3507 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210508/5036c9c7/attachment.bin>


More information about the libcxx-commits mailing list