From e0aa19a94e0d2091013668b67961d885c6d5b7bd Mon Sep 17 00:00:00 2001 From: Haobo Xu Date: Wed, 25 Sep 2013 14:35:01 -0700 Subject: [PATCH] [RocbsDB] Add an option to enable set based memtable for perf_context_test Summary: as title. Some result: -- Sequential insertion of 1M key/value with stock skip list (all in on memtable) time ./perf_context_test --total_keys=1000000 --use_set_based_memetable=0 Inserting 1000000 key/value pairs ... Put uesr key comparison: Count: 1000000 Average: 8.0179 StdDev: 176.34 Min: 0.0000 Median: 2.5555 Max: 88933.0000 Percentiles: P50: 2.56 P75: 2.83 P99: 58.21 P99.9: 133.62 P99.99: 987.50 Get uesr key comparison: Count: 1000000 Average: 43.4465 StdDev: 379.03 Min: 2.0000 Median: 36.0195 Max: 88939.0000 Percentiles: P50: 36.02 P75: 43.66 P99: 112.98 P99.9: 824.84 P99.99: 7615.38 real 0m21.345s user 0m14.723s sys 0m5.677s -- Sequential insertion of 1M key/value with set based memtable (all in on memtable) time ./perf_context_test --total_keys=1000000 --use_set_based_memetable=1 Inserting 1000000 key/value pairs ... Put uesr key comparison: Count: 1000000 Average: 61.5022 StdDev: 6.49 Min: 0.0000 Median: 62.4295 Max: 71.0000 Percentiles: P50: 62.43 P75: 66.61 P99: 71.00 P99.9: 71.00 P99.99: 71.00 Get uesr key comparison: Count: 1000000 Average: 29.3810 StdDev: 3.20 Min: 1.0000 Median: 29.1801 Max: 34.0000 Percentiles: P50: 29.18 P75: 32.06 P99: 34.00 P99.9: 34.00 P99.99: 34.00 real 0m28.875s user 0m21.699s sys 0m5.749s Worst case comparison for a Put is 88933 (skiplist) vs 71 (set based memetable) Of course, there's other in-efficiency in set based memtable implementation, which lead to the overall worst performance. However, P99 behavior advantage is very very obvious. Test Plan: ./perf_context_test and viewstate shadow testing Reviewers: dhruba Reviewed By: dhruba CC: leveldb Differential Revision: https://reviews.facebook.net/D13095 --- db/perf_context_test.cc | 61 ++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/db/perf_context_test.cc b/db/perf_context_test.cc index 9f98a33ef..08f2c7369 100644 --- a/db/perf_context_test.cc +++ b/db/perf_context_test.cc @@ -9,6 +9,7 @@ #include "util/testharness.h" bool FLAGS_random_key = false; +bool FLAGS_use_set_based_memetable = false; int FLAGS_total_keys = 100; int FLAGS_write_buffer_size = 1000000000; int FLAGS_max_write_buffer_number = 8; @@ -27,6 +28,13 @@ std::shared_ptr OpenDb() { options.max_write_buffer_number = FLAGS_max_write_buffer_number; options.min_write_buffer_number_to_merge = FLAGS_min_write_buffer_number_to_merge; + + if (FLAGS_use_set_based_memetable) { + auto prefix_extractor = leveldb::NewFixedPrefixTransform(0); + options.memtable_factory = + std::make_shared(prefix_extractor); + } + Status s = DB::Open(options, kDbName, &db); ASSERT_OK(s); return std::shared_ptr(db); @@ -80,36 +88,35 @@ void ProfileKeyComparison() { WriteOptions write_options; ReadOptions read_options; - uint64_t total_user_key_comparison_get = 0; - uint64_t total_user_key_comparison_put = 0; - uint64_t max_user_key_comparison_get = 0; + HistogramImpl hist_put; + HistogramImpl hist_get; std::cout << "Inserting " << FLAGS_total_keys << " key/value pairs\n...\n"; + std::vector keys; for (int i = 0; i < FLAGS_total_keys; ++i) { + keys.push_back(i); + } + + if (FLAGS_random_key) { + std::random_shuffle(keys.begin(), keys.end()); + } + + for (const int i : keys) { std::string key = "k" + std::to_string(i); std::string value = "v" + std::to_string(i); perf_context.Reset(); db->Put(write_options, key, value); - total_user_key_comparison_put += perf_context.user_key_comparison_count; + hist_put.Add(perf_context.user_key_comparison_count); perf_context.Reset(); db->Get(read_options, key, &value); - total_user_key_comparison_get += perf_context.user_key_comparison_count; - max_user_key_comparison_get = - std::max(max_user_key_comparison_get, - perf_context.user_key_comparison_count); + hist_get.Add(perf_context.user_key_comparison_count); } - std::cout << "total user key comparison get: " - << total_user_key_comparison_get << "\n" - << "total user key comparison put: " - << total_user_key_comparison_put << "\n" - << "max user key comparison get: " - << max_user_key_comparison_get << "\n" - << "avg user key comparison get:" - << total_user_key_comparison_get/FLAGS_total_keys << "\n"; + std::cout << "Put uesr key comparison: \n" << hist_put.ToString() + << "Get uesr key comparison: \n" << hist_get.ToString(); } @@ -160,7 +167,9 @@ TEST(PerfContextTest, SeekKeyComparison) { db->Put(write_options, key, value); } - HistogramImpl histogram; + HistogramImpl hist_seek; + HistogramImpl hist_next; + for (int i = 0; i < FLAGS_total_keys; ++i) { std::string key = "k" + std::to_string(i); std::string value = "v" + std::to_string(i); @@ -170,9 +179,18 @@ TEST(PerfContextTest, SeekKeyComparison) { iter->Seek(key); ASSERT_TRUE(iter->Valid()); ASSERT_EQ(iter->value().ToString(), value); - histogram.Add(perf_context.user_key_comparison_count); + hist_seek.Add(perf_context.user_key_comparison_count); } - std::cout << histogram.ToString(); + + std::unique_ptr iter(db->NewIterator(read_options)); + for (iter->SeekToFirst(); iter->Valid();) { + perf_context.Reset(); + iter->Next(); + hist_next.Add(perf_context.user_key_comparison_count); + } + + std::cout << "Seek:\n" << hist_seek.ToString() + << "Next:\n" << hist_next.ToString(); } } @@ -196,6 +214,11 @@ int main(int argc, char** argv) { FLAGS_random_key = n; } + if (sscanf(argv[i], "--use_set_based_memetable=%d%c", &n, &junk) == 1 && + (n == 0 || n == 1)) { + FLAGS_use_set_based_memetable = n; + } + } std::cout << kDbName << "\n";