From 121fa4ff469456bd21cda3f140f0788e1198d2bc Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Wed, 25 Mar 2015 10:25:26 +0100 Subject: [PATCH] test: Introduce test for in-memory CQL query performance The schema and queries resemble that used by cassandra-stress. Results on my laptop: $ build/release/tests/perf/perf_simple_query -c1 Concurrency = 100 x 1 Creating 1000 partitions... Timing single key selects... 452146.50 tps 449365.24 tps 457650.58 tps 460334.78 tps 458281.51 tps Timing random key selects... 439181.03 tps 449899.67 tps 405146.90 tps 440228.84 tps 440889.50 tps $ build/release/tests/perf/perf_simple_query -c3 Concurrency = 100 x 3 Creating 1000 partitions... Timing single key selects... 302615.08 tps 301471.02 tps 303040.67 tps 302114.77 tps 302465.13 tps Timing random key selects... 627516.46 tps 628978.04 tps 623664.15 tps 624098.48 tps 614549.85 tps --- configure.py | 1 + tests/perf/perf_simple_query.cc | 77 +++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/perf/perf_simple_query.cc diff --git a/configure.py b/configure.py index 154b7c954b..6755582923 100755 --- a/configure.py +++ b/configure.py @@ -121,6 +121,7 @@ urchin_tests = [ 'tests/urchin/types_test', 'tests/perf/perf_mutation', 'tests/perf/perf_cql_parser', + 'tests/perf/perf_simple_query', 'tests/urchin/cql_query_test', 'tests/test-serialization', 'tests/urchin/sstable_test', diff --git a/tests/perf/perf_simple_query.cc b/tests/perf/perf_simple_query.cc new file mode 100644 index 0000000000..daf3758647 --- /dev/null +++ b/tests/perf/perf_simple_query.cc @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +#include +#include "tests/urchin/cql_test_env.hh" +#include "tests/perf/perf.hh" +#include "core/app-template.hh" + +static const sstring table_name = "cf"; + +static sstring make_key(int sequence) { + return sprint("0xdeadbeefcafebabe%04d", sequence); +}; + +static auto execute_update_for_key(cql_test_env& env, const sstring& key) { + return env.execute_cql(sprint("UPDATE cf SET " + "\"C0\" = 0x8f75da6b3dcec90c8a404fb9a5f6b0621e62d39c69ba5758e5f41b78311fbb26cc7a," + "\"C1\" = 0xa8761a2127160003033a8f4f3d1069b7833ebe24ef56b3beee728c2b686ca516fa51," + "\"C2\" = 0x583449ce81bfebc2e1a695eb59aad5fcc74d6d7311fc6197b10693e1a161ca2e1c64," + "\"C3\" = 0x62bcb1dbc0ff953abc703bcb63ea954f437064c0c45366799658bd6b91d0f92908d7," + "\"C4\" = 0x222fcbe31ffa1e689540e1499b87fa3f9c781065fccd10e4772b4c7039c2efd0fb27 " + "WHERE \"KEY\"=%s;", key)).discard_result(); +}; + +static auto constexpr n_partitons = 1000; +static auto constexpr concurrency = 100; + +future<> do_test(cql_test_env& env) { + std::cout << "Concurrency = " << concurrency << " x " << smp::count << std::endl; + auto keys = make_shared>(); + + return env.create_table([] (auto ks_name) { + return schema(ks_name, "cf", + {{"KEY", bytes_type}}, + {}, + {{"C0", bytes_type}, {"C1", bytes_type}, {"C2", bytes_type}, {"C3", bytes_type}, {"C4", bytes_type}}, + {}, + utf8_type); + }).then([&env, keys] { + std::cout << "Creating " << n_partitons << " partitions..." << std::endl; + auto partitions = boost::irange(0, n_partitons); + return do_for_each(partitions.begin(), partitions.end(), [&env, keys] (int sequence) { + auto key = make_key(sequence); + keys->push_back(bytes(key)); + return execute_update_for_key(env, key); + }); + }).then([&env] { + return env.prepare("select \"C0\", \"C1\", \"C2\", \"C3\", \"C4\" from cf where \"KEY\" = ?"); + }).then([&env, keys] (auto id) { + std::cout << "Timing single key selects..." << std::endl; + return time_parallel([&env, id, keys] { + auto& key = keys->at(0); + return env.execute_prepared(id, {{key}}).discard_result(); + }, concurrency) + .then([&env, id, keys] () { + std::cout << "Timing random key selects..." << std::endl; + return time_parallel([&env, id, keys] { + auto& key = keys->at(std::rand() % keys->size()); + return env.execute_prepared(id, {{key}}).discard_result(); + }, concurrency); + }); + }); +} + +int main(int argc, char** argv) { + app_template app; + return app.run(argc, argv, [] { + make_env_for_test().then([] (auto env) { + return do_test(*env).finally([env] { + return env->stop().finally([env] {}); + }); + }).then([] { + return engine().exit(0); + }).or_terminate(); + }); +}