// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include #include #include #include #include #include LOG_SETUP("sort_benchmark"); using namespace vespalib; class Test : public TestApp { public: private: template vespalib::Array create(size_t count); template void sortDirect(size_t count); template void sortInDirect(size_t count); int Main() override; }; template class TT { public: TT(uint64_t v) : _v(v) { } bool operator < (const TT & rhs) const { return _v < rhs._v; } private: uint64_t _v; uint8_t _payLoad[N - sizeof(uint64_t)]; }; template class I { public: I(const T * p) : _p(p) { } bool operator < (const I & rhs) const { return *_p < *rhs._p; } private: const T * _p; }; template vespalib::Array Test::create(size_t count) { vespalib::Array v; v.reserve(count); srand(0); for (size_t i(0); i < count; i++) { v.push_back(rand()); } return v; } template void Test::sortDirect(size_t count) { vespalib::Array v(create(count)); LOG(info, "Running sortDirect with %ld count and payload of %ld", v.size(), sizeof(T)); for (size_t j=0; j < 10; j++) { vespalib::Array t(v); std::sort(t.begin(), t.end()); } } template void Test::sortInDirect(size_t count) { vespalib::Array k(create(count)); LOG(info, "Running sortInDirect with %ld count and payload of %ld", k.size(), sizeof(T)); vespalib::Array< I > v; v.reserve(k.size()); for (size_t i(0), m(k.size()); i < m; i++) { v.push_back(&k[i]); } for (size_t j=0; j < 10; j++) { vespalib::Array< I > t(v); std::sort(t.begin(), t.end()); } } int Test::Main() { std::string type("sortdirect"); size_t count = 1000000; size_t payLoad = 0; if (_argc > 1) { type = _argv[1]; } if (_argc > 2) { count = strtol(_argv[2], NULL, 0); } if (_argc > 3) { payLoad = strtol(_argv[3], NULL, 0); } TEST_INIT("sort_benchmark"); steady_time start(steady_clock::now()); if (payLoad < 8) { using T = TT<8>; if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } else if (payLoad < 16) { using T = TT<16>; if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } else if (payLoad < 32) { using T = TT<32>; if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } else if (payLoad < 64) { using T = TT<64>; if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } else if (payLoad < 128) { using T = TT<128>; if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } else if (payLoad < 256) { using T = TT<256>; if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } else if (payLoad < 512) { using T = TT<512>; if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } else { using T = TT<1024>; LOG(info, "Payload %ld is too big to make any sense. Using %ld.", payLoad, sizeof(T)); if (type == "sortdirect") { sortDirect(count); } else if (type == "sortindirect") { sortInDirect(count); } else { LOG(warning, "type '%s' is unknown", type.c_str()); } } LOG(info, "rusage = {\n%s\n}", vespalib::RUsage::createSelf(start).toString().c_str()); ASSERT_EQUAL(0, kill(0, SIGPROF)); TEST_DONE(); } TEST_APPHOOK(Test);