Use boost::flat_map for better performance

bench_vv_getdelta/512/1024     8768606 ns      8768555 ns           80 Tags=512 getDeltaTimes=1024 items_per_second=116.781k/s
This commit is contained in:
Jingyu Zhou 2022-03-10 21:36:03 -08:00
parent 6dbbee347d
commit 5450b740ac
3 changed files with 55 additions and 8 deletions

View File

@ -23,15 +23,14 @@
#pragma once
#include <map>
#include <boost/container/flat_map.hpp>
#include <set>
#include <unordered_map>
#include "fdbclient/FDBTypes.h"
#include "fdbclient/Knobs.h"
struct VersionVector {
std::map<Tag, Version> versions;
boost::container::flat_map<Tag, Version> versions;
Version maxVersion; // Specifies the max version in this version vector. (Note:
// there may or may not be a corresponding entry for this
// version in the "versions" map.)

View File

@ -21,6 +21,7 @@
#pragma once
#include <algorithm>
#include <boost/container/flat_map.hpp>
#include <iterator>
#include <cstring>
#include <functional>
@ -227,6 +228,30 @@ struct vector_like_traits<std::unordered_map<Key, T, Hash, Pred, Allocator>> : s
}
};
template <class Key, class T, class Compare, class Allocator>
struct vector_like_traits<boost::container::flat_map<Key, T, Compare, Allocator>> : std::true_type {
using Vec = boost::container::flat_map<Key, T, Compare, Allocator>;
using value_type = std::pair<Key, T>;
using iterator = typename Vec::const_iterator;
using insert_iterator = std::insert_iterator<Vec>;
template <class Context>
static size_t num_entries(const Vec& v, Context&) {
return v.size();
}
template <class Context>
static void reserve(Vec& v, size_t size, Context&) {}
template <class Context>
static insert_iterator insert(Vec& v, Context&) {
return std::inserter(v, v.end());
}
template <class Context>
static iterator begin(const Vec& v, Context&) {
return v.begin();
}
};
template <class Key, class Compare, class Allocator>
struct vector_like_traits<std::set<Key, Compare, Allocator>> : std::true_type {
using Vec = std::set<Key, Compare, Allocator>;

View File

@ -22,17 +22,19 @@
#define FLOW_SERIALIZE_H
#pragma once
#include <stdint.h>
#include <algorithm>
#include <array>
#include <boost/container/flat_map.hpp>
#include <deque>
#include <set>
#include "flow/ProtocolVersion.h"
#include "flow/Error.h"
#include <stdint.h>
#include "flow/Arena.h"
#include "flow/Error.h"
#include "flow/FileIdentifier.h"
#include "flow/ObjectSerializer.h"
#include "flow/ProtocolVersion.h"
#include "flow/network.h"
#include <algorithm>
#include <deque>
// Though similar, is_binary_serializable cannot be replaced by std::is_pod, as doing so would prefer
// memcpy over a defined serialize() method on a POD struct. As not all of our structs are packed,
@ -268,6 +270,27 @@ inline void load(Archive& ar, std::map<K, V>& value) {
ASSERT(ar.protocolVersion().isValid());
}
template <class Archive, class K, class V>
inline void save(Archive& ar, const boost::container::flat_map<K, V>& value) {
ar << (int)value.size();
for (const auto& it : value) {
ar << it.first << it.second;
}
ASSERT(ar.protocolVersion().isValid());
}
template <class Archive, class K, class V>
inline void load(Archive& ar, boost::container::flat_map<K, V>& value) {
int s;
ar >> s;
value.clear();
for (int i = 0; i < s; ++i) {
std::pair<K, V> p;
ar >> p.first >> p.second;
value.emplace(p);
}
ASSERT(ar.protocolVersion().isValid());
}
#ifdef _MSC_VER
#pragma intrinsic(memcpy)
#endif