Commit 5bdd0585 authored by Xiao Shi's avatar Xiao Shi Committed by Facebook Github Bot

use F14NodeMap in folly::dynamic

Summary:
F14NodeMap is a safe drop-in replacement for std::unordered_map. It is smaller
than std::unordered_map (32 bytes instead of 56 bytes) and has been shown
to be faster in many production use cases. This diff replaces the hash table
inside folly::dynamic. The effect is that sizeof(folly::dynamic) will drop from 64
bytes to 40 bytes, and use cases that use folly::dynamic as an object may also
get a CPU win.

Reviewed By: nbronson

Differential Revision: D9518110

fbshipit-source-id: 72daba13577c560bbb88c4d68a457afedf1af38e
parent 1f3931f4
......@@ -141,13 +141,13 @@ dynamic numericOp(dynamic const& a, dynamic const& b) {
/*
* We're doing this instead of a simple member typedef to avoid the
* undefined behavior of parameterizing std::unordered_map<> with an
* undefined behavior of parameterizing F14NodeMap<> with an
* incomplete type.
*
* Note: Later we may add separate order tracking here (a multi-index
* type of thing.)
*/
struct dynamic::ObjectImpl : std::unordered_map<dynamic, dynamic> {};
struct dynamic::ObjectImpl : F14NodeMap<dynamic, dynamic> {};
//////////////////////////////////////////////////////////////////////
......@@ -855,10 +855,11 @@ struct dynamic::GetAddrImpl<std::string> {
}
};
template <> struct dynamic::GetAddrImpl<dynamic::ObjectImpl> {
static_assert(sizeof(ObjectImpl) <= sizeof(Data::objectBuffer),
"In your implementation, std::unordered_map<> apparently takes different"
" amount of space depending on its template parameters. This is "
"weird. Make objectBuffer bigger if you want to compile dynamic.");
static_assert(
sizeof(ObjectImpl) <= sizeof(Data::objectBuffer),
"In your implementation, F14NodeMap<> apparently takes different"
" amount of space depending on its template parameters. This is "
"weird. Make objectBuffer bigger if you want to compile dynamic.");
static ObjectImpl* get(Data& d) noexcept {
void* data = &d.objectBuffer;
......
......@@ -57,7 +57,6 @@
#include <ostream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
......@@ -65,6 +64,7 @@
#include <folly/Range.h>
#include <folly/Traits.h>
#include <folly/container/F14Map.h>
#include <folly/json_pointer.h>
namespace folly {
......@@ -608,15 +608,14 @@ struct dynamic : private boost::operators<dynamic> {
/*
* Objects are placement new'd here. We have to use a char buffer
* because we don't know the type here (std::unordered_map<> with
* because we don't know the type here (F14NodeMap<> with
* dynamic would be parameterizing a std:: template with an
* incomplete type right now). (Note that in contrast we know it
* is ok to do this with fbvector because we own it.)
*/
std::aligned_storage<
sizeof(std::unordered_map<int,int>),
alignof(std::unordered_map<int,int>)
>::type objectBuffer;
sizeof(F14NodeMap<int, int>),
alignof(F14NodeMap<int, int>)>::type objectBuffer;
} u_;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment