Skip to content

@sztomi /func_try_block.cpp
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
This file demonstrates the usage of function try blocks for implementing thread-safe copy constructors. Note, that the equality operator for ExpensiveFoo is omitted (implicitly default), so in reality, there would be even more time spent in the BarSlow copy constructor than in this example.
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
struct ExpensiveFoo
{
ExpensiveFoo()
{
std::cout << "ExpensiveFoo default constructor... ";
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "done.\n";
}
ExpensiveFoo(ExpensiveFoo const& other)
{
std::cout << "ExpensiveFoo copy constructor... ";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "done.\n";
}
~ExpensiveFoo()
{
std::cout << "~ExpensiveFoo\n";
}
private:
char data[10000];
};
struct BarSlow
{
BarSlow() = default;
BarSlow(const BarSlow& other)
{
std::cout << "BarSlow copy constructor body\n";
std::lock_guard<std::mutex> lock(m);
expensive = other.expensive;
}
private:
mutable std::mutex m;
ExpensiveFoo expensive;
};
struct BarFast
{
BarFast() = default;
BarFast(const BarFast& other)
try
: expensive((other.m.lock(), other.expensive))
{
std::cout << "BarFast copy constructor body\n";
other.m.unlock();
}
catch (...)
{
std::cout << "BarFast copy constructor catch block\n";
other.m.unlock();
}
private:
mutable std::mutex m;
ExpensiveFoo expensive;
};
void f(BarSlow slow) {}
void f(BarFast fast) {}
int main()
{
std::cout << "Starting main.\n";
BarSlow slow;
BarFast fast;
std::cout << "\n\nMeasuring simple implementation.\n\n";
auto start = std::chrono::system_clock::now();
f(slow);
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << ">>> BarSlow thread-safe copy: " << elapsed.count() << "ms\n";
std::cout << "\n\nMeasuring implementation with function try block.\n\n";
start = std::chrono::system_clock::now();
f(fast);
end = std::chrono::system_clock::now();
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << ">>> BarFast thread-safe copy: " << elapsed.count() << "ms\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.