Skip to content

Instantly share code, notes, and snippets.

@eao197
Created January 19, 2024 07:20
Show Gist options
  • Save eao197/54a91fb2e941ccf02a6b5512ed19ba88 to your computer and use it in GitHub Desktop.
Save eao197/54a91fb2e941ccf02a6b5512ed19ba88 to your computer and use it in GitHub Desktop.
Примитивный бенчмарк для демонстрации скорости работы разных реализаций isDefault
#include <chrono>
#include <iostream>
#include <string>
#include <variant>
namespace isdefault_benchmark
{
class time_meter_t
{
const std::string m_operation_name;
const std::chrono::high_resolution_clock::time_point m_started_at;
public:
time_meter_t(
std::string operation_name )
: m_operation_name{ std::move(operation_name) }
, m_started_at{ std::chrono::high_resolution_clock::now() }
{}
~time_meter_t()
{
const auto finished_at = std::chrono::high_resolution_clock::now();
const auto r = std::chrono::duration_cast< std::chrono::microseconds >(
finished_at - m_started_at );
std::cout << m_operation_name << ": " << r.count() << "us" << std::endl;
}
};
using Data_t = std::variant<std::string, double>;
[[nodiscard]] bool isDefault(const Data_t & d)
{
if(std::holds_alternative<std::string>(d))
return std::get<std::string>(d) == "";
else
return std::get<double>(d) == 0.0;
}
[[nodiscard]] bool isDefaultStringEmpty(const Data_t & d)
{
if(std::holds_alternative<std::string>(d))
return std::get<std::string>(d).empty();
else
return std::get<double>(d) == 0.0;
}
[[nodiscard]] bool isDefaultViaVisitor(const Data_t & d)
{
struct IsDefaultValueVisitor {
bool operator()(const std::string & v) const { return v.empty(); }
bool operator()(const double & v) const { return v == 0.0; }
};
return std::visit(IsDefaultValueVisitor{}, d);
}
template<typename Functor>
std::size_t process(
const std::vector<Data_t> & data,
Functor functor)
{
std::size_t r{};
for(int i = 0; i < 1'000'000; ++i)
{
for(const auto & d : data)
r += (functor(d) ? 1 : 0);
}
return r;
}
void do_benchmark()
{
std::vector<Data_t> data{
{ std::string{} },
{ 0.0 },
{ 1.34 },
{ 4.7 },
{ 0.0 },
{ std::string{"Hello, World"} },
{ 43.0 },
{ std::string{"The quick brown fox jumps over the lazy dog"} },
{ std::string{} },
{ std::string{""} },
{ 0.0 },
{ std::string{"One, Two, Three, Four, Five, ..."} },
{ std::string{"1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15"} },
{ std::string{"short"} },
{ std::string{"======= long ======="} },
{ std::string{"yet more ======= long ======= string"} },
{ 10.0 },
{ 11.0 },
{ 12.0 }
};
std::size_t r{};
{
time_meter_t meter{ "default implementation of isDefault" };
r = process(data, isDefault);
}
std::cout << "r=" << r << std::endl;
{
time_meter_t meter{ "modified implementation of isDefault (string.empty())" };
r = process(data, isDefaultStringEmpty);
}
std::cout << "r=" << r << std::endl;
{
time_meter_t meter{ "visit-based implementation of isDefault" };
r = process(data, isDefaultViaVisitor);
}
std::cout << "r=" << r << std::endl;
}
} /* namespace isdefault_benchmark */
using namespace isdefault_benchmark;
int main()
{
do_benchmark();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment