Fix an inefficiency in json-serializing a dynamic with sorted keys
authorYedidya Feldblum <yfeldblum@fb.com>
Tue, 10 Jan 2017 19:57:31 +0000 (11:57 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Tue, 10 Jan 2017 20:03:05 +0000 (12:03 -0800)
Summary:
[Folly] Fix an inefficiency in json-serializing a `dynamic` with sorted keys.

The inefficiency is that, at each level of the `dynamic` which is map-typed, we effectively make a full copy of the `dynamic` object. This can be expensive.

Reviewed By: Gownta

Differential Revision: D4389671

fbshipit-source-id: 223739397f913d3e65a421a9a4dcb089ec757ec6

folly/json.cpp

index 6f8ecdbc4d443292abfd49ff1cabaef4c284e814..4449e7799d147c04dd905728ca3d538752abad40 100644 (file)
  */
 
 #include <folly/json.h>
+
+#include <algorithm>
 #include <cassert>
+#include <functional>
+
 #include <boost/next_prior.hpp>
 #include <boost/algorithm/string.hpp>
 
@@ -111,13 +115,13 @@ private:
     indent();
     newline();
     if (opts_.sort_keys) {
-      std::vector<std::pair<dynamic, dynamic>> items(
-        o.items().begin(), o.items().end());
-      std::sort(items.begin(), items.end(), [](auto const& a, auto const& b) {
+      using ref = std::reference_wrapper<decltype(o.items())::value_type const>;
+      std::vector<ref> refs(o.items().begin(), o.items().end());
+      std::sort(refs.begin(), refs.end(), [](ref a, ref b) {
         // Only compare keys.  No ordering among identical keys.
-        return a.first < b.first;
+        return a.get().first < b.get().first;
       });
-      printKVPairs(items.begin(), items.end());
+      printKVPairs(refs.cbegin(), refs.cend());
     } else {
       printKVPairs(o.items().begin(), o.items().end());
     }