Commit 7ba6988b authored by Matt Diffenderfer's avatar Matt Diffenderfer Committed by Facebook GitHub Bot

Use list::splice to move lru nodes

Summary:
By using `list::splice`, we can avoid making a call to create and delete nodes. By doing so, only internal pointers are reassigned.

`list::splice` documentation: https://www.boost.org/doc/libs/1_67_0/doc/html/boost/intrusive/list.html#idp55504432-bb

Reviewed By: yfeldblum

Differential Revision: D22369091

fbshipit-source-id: efde0f520f81506b96272b320ae9d65ce1cabcb2
parent 43d80f11
...@@ -256,8 +256,7 @@ class EvictingCacheMap { ...@@ -256,8 +256,7 @@ class EvictingCacheMap {
if (it == index_.end()) { if (it == index_.end()) {
return end(); return end();
} }
lru_.erase(lru_.iterator_to(*it)); lru_.splice(lru_.begin(), lru_, lru_.iterator_to(*it));
lru_.push_front(*it);
return iterator(lru_.iterator_to(*it)); return iterator(lru_.iterator_to(*it));
} }
...@@ -343,8 +342,7 @@ class EvictingCacheMap { ...@@ -343,8 +342,7 @@ class EvictingCacheMap {
if (it != index_.end()) { if (it != index_.end()) {
it->pr.second = std::move(value); it->pr.second = std::move(value);
if (promote) { if (promote) {
lru_.erase(lru_.iterator_to(*it)); lru_.splice(lru_.begin(), lru_, lru_.iterator_to(*it));
lru_.push_front(*it);
} }
} else { } else {
auto node = new Node(key, std::move(value)); auto node = new Node(key, std::move(value));
......
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/container/EvictingCacheMap.h>
#include <folly/Benchmark.h>
using namespace folly;
// This function creates a cache of size `numElts` and scans through it `n`
// times in order to cause the most churn in the LRU structure as possible.
// This is meant to exercise the performance of the lookup path in the cache,
// most notably promotions within the LRU.
void scanCache(uint32_t n, size_t numElts) {
BenchmarkSuspender suspender;
EvictingCacheMap<size_t, size_t> m(numElts);
for (size_t i = 0; i < numElts; ++i) {
m.insert(i, i);
}
suspender.dismissing([&]() {
for (uint32_t i = 0; i < n; ++i) {
for (size_t j = 0; j < numElts; ++j) {
m.get(j);
}
}
});
}
BENCHMARK_PARAM(scanCache, 1000) // 1K
BENCHMARK_PARAM(scanCache, 10000) // 10K
BENCHMARK_PARAM(scanCache, 100000) // 100K
BENCHMARK_PARAM(scanCache, 1000000) // 1M
int main() {
runBenchmarks();
}
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