Create TinyUnorderedMap class for small-N data storage.
Our code relies on std::unordered_map for storage of unordered data. Unfortunately, while unordered_map is algorithmically quite efficient, in many real-world scenarios--particularly with small amounts of data-- a simple vector with linear search runs rings around it. This CL doubles the performance of `nanobench -m sksl_large`: http://screen/7uGYGLCaTtaHU4j Change-Id: Ia2f6cedfac338876c2da57642e9b34addd85b683 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/322320 Commit-Queue: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
750261f41a
commit
b16b29a9fe
@ -45,6 +45,7 @@ skia_sksl_sources = [
|
||||
"$_src/sksl/SkSLString.cpp",
|
||||
"$_src/sksl/SkSLString.h",
|
||||
"$_src/sksl/SkSLStringStream.h",
|
||||
"$_src/sksl/SkSLTinyUnorderedMap.h",
|
||||
"$_src/sksl/SkSLUtil.cpp",
|
||||
"$_src/sksl/SkSLUtil.h",
|
||||
"$_src/sksl/ir/SkSLBinaryExpression.h",
|
||||
|
66
src/sksl/SkSLTinyUnorderedMap.h
Normal file
66
src/sksl/SkSLTinyUnorderedMap.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_TINYUNORDEREDMAP
|
||||
#define SKSL_TINYUNORDEREDMAP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/** The TinyUnorderedMap presents a minimal, unordered_map-like interface, but is backed by a normal
|
||||
vector. No attempt is made to be clever during lookups or insertions. This is intended to be
|
||||
used in cases where we have tiny amount of data (e.g. less than 50 elements); CPUs are really
|
||||
good at scanning contiguous cachelines. */
|
||||
template <typename K, typename V>
|
||||
class TinyUnorderedMap {
|
||||
public:
|
||||
using key_type = K;
|
||||
using mapped_type = V;
|
||||
using value_type = std::pair<const K, V>;
|
||||
using iterator = typename std::vector<value_type>::iterator;
|
||||
using const_iterator = typename std::vector<value_type>::const_iterator;
|
||||
|
||||
iterator begin() { return fData.begin(); }
|
||||
const_iterator begin() const { return fData.begin(); }
|
||||
|
||||
iterator end() { return fData.end(); }
|
||||
const_iterator end() const { return fData.end(); }
|
||||
|
||||
void clear() { fData.clear(); }
|
||||
bool empty() { return fData.empty(); }
|
||||
size_t size() { return fData.size(); }
|
||||
void reserve(size_t amount) { fData.reserve(amount); }
|
||||
|
||||
iterator find(const K& key) {
|
||||
return std::find_if(fData.begin(), fData.end(),
|
||||
[&](const value_type& a) { return a.first == key; });
|
||||
}
|
||||
const_iterator find(const K& key) const {
|
||||
return std::find_if(fData.begin(), fData.end(),
|
||||
[&](const value_type& a) { return a.first == key; });
|
||||
}
|
||||
|
||||
V& operator[](const K& key) {
|
||||
auto iter = this->find(key);
|
||||
if (iter != fData.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
fData.push_back(value_type{key, V{}});
|
||||
return fData.back().second;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<value_type> fData;
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
#ifndef SKSL_EXPRESSION
|
||||
#define SKSL_EXPRESSION
|
||||
|
||||
#include "src/sksl/SkSLTinyUnorderedMap.h"
|
||||
#include "src/sksl/ir/SkSLStatement.h"
|
||||
#include "src/sksl/ir/SkSLType.h"
|
||||
|
||||
@ -19,7 +20,7 @@ struct Expression;
|
||||
class IRGenerator;
|
||||
struct Variable;
|
||||
|
||||
typedef std::unordered_map<const Variable*, std::unique_ptr<Expression>*> DefinitionMap;
|
||||
using DefinitionMap = TinyUnorderedMap<const Variable*, std::unique_ptr<Expression>*>;
|
||||
|
||||
/**
|
||||
* Abstract supertype of all expressions.
|
||||
|
Loading…
Reference in New Issue
Block a user