Seer
Branch | Status |
---|---|
Master | |
Develop |
A single header performance logger outputting to chrome tracing in C++11 for windows, linux and mac, readable using chrome://tracing
Example when loaded in chrome://tracing
Install:
Drop Seer.hpp in to your include path and you should be good to go.
Functions:
Getting output and memory usage:
Speed:
Tests:
Functions:
ScopeTimer:
ScopeTimer
will measure the time spent in a block/scope.
{
seer::ScopeTimer("test"); // This will measure 2 seconds.
std::this_thread::sleep_for(2s);
}
Timer:
If ScopeTimer can not be used, or more manual control over the end time is required Timer
will measure the time from object creation to end member call.
{
seer::Timer test("test");
std::this_thread::sleep_for(2s);
test.end();
}
Async:
Async
allows you to draw visual connections between scopes timers, this shows up in chrome as arrows joining blocks.
This is handy for tracking events across threads or separated by time.
Across Threads:
seer::Async async;
{
const auto timer = async.create_timer("Step 1");
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::async(std::launch::async, [async] {
const auto timer2 = async.create_timer("Step 2");
std::this_thread::sleep_for(std::chrono::seconds(1));
}).get();
{
const auto timer3 = async.create_timer("Step 3");
std::this_thread::sleep_for(std::chrono::seconds(1));
}
Across time:
seer::Async async;
{
const auto timer = async.create_timer("Step 1");
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// some other work
{
const auto timer2 = async.create_timer("Step 2");
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// some more work
{
const auto timer3 = async.create_timer("Step 3");
std::this_thread::sleep_for(std::chrono::seconds(1));
}
Counter:
Counter
can be used for tracking a value over time.
Note: multiple counters sharing the same name will appear in the same chrome trace.
{
seer::Counter<int> counter("test", 1);
std::this_thread::sleep_for(2s);
counter.update(2);
}
instant_event:
Will place an instant event scoped to either process (default), thread, globally.
{
seer::instant_event("test"); // process
seer::instant_event("test", seer::InstantEventScope::thread); // process
seer::instant_event("test", seer::InstantEventScope::global); // global
}
Thread:
Process:
Global:
mark:
Will produce a mark.
{
seer::mark("test");
}
set_thread_name:
Will name the current thread or optional with another threads id.
{
seer::set_thread_name("render");
seer::set_thread_name("worker", worker.id);
}
set_process_name:
Will name the current process.
{
seer::set_process_name("my amazing app"); // this can be called at any point in time
}
Getting output and memory usage:
output:
chrome://tracing expects a json file, this can be fetched in several way.
Interface to this data can be found through seer::buffer
{
seer::buffer.dump_to_file("my profile data.json"); //defaults to "profile.json"
file << seer::buffer; //by stream
std::string json = seer::buffer.str(); //by string
}
buffer and memory usage:
Internally Seer allocates a buffer of memory to write to, this defaults to ~10mb. Monitoring and changes to this buffer can be found through seer::buffer
{
// usage
seer::buffer.usage().usage_in_bytes;
seer::buffer.usage().total_in_bytes;
seer::buffer.usage().percent_used;
// resize
seer::buffer.resize(1000000000); // resize to 1gb
// clear
seer::buffer.clear();
}
buffer filled behaviour:
When the internal buffer fills up by default it resets and starts a fresh, chucking out its old data, however this can be customised
{
seer::buffer_overflow_behaviour = seer::BufferOverflowBehaviour::reset;
// the default, the buffer forgets its old data and starts again
seer::buffer_overflow_behaviour = seer::BufferOverflowBehaviour::expand;
// the buffer will grow on its own with no upper limit
seer::buffer_overflow_behaviour = seer::BufferOverflowBehaviour::discard;
// the buffer will discard all new events once it fills
}
Speed:
benchmarks:
While seer may be header only, these benchmarks use google benchmark and require building.
Dependencies (included in the repo):
Mac and linux:
git clone https://github.com/ThomasMonkman/Seer.git
cd ./Seer
mkdir build && cd build/
cmake -DCMAKE_BUILD_TYPE=Release ../
make
benchmarks/seer_benchmark
Windows:
Simply open the repo in visual studio 17, and with its new cmake features and you should just be able to run the projects, make sure you use release.
Test:
test:
While seer may be header only, these tests use catch 2 and require building.
Dependencies (included in the repo):
Mac and linux:
git clone https://github.com/ThomasMonkman/Seer.git
cd ./Seer
mkdir build && cd build/
cmake -DCMAKE_BUILD_TYPE=Release ../
make
tests/seer_unit
Windows:
Simply open the repo in visual studio 17, and with its new cmake features and you should just be able to run the projects.
Example code:
{
seer::set_process_name("my amazing app");
seer::set_thread_name("render");
seer::instant_event("frame start", seer::InstantEventScope::process);
seer::Counter<int> temperature("temperature", 0);
seer::Async async;
seer::ScopeTimer frame("frame");
std::this_thread::sleep_for(std::chrono::seconds(1));
temperature.update(2);
{
seer::ScopeTimer input("get input");
std::this_thread::sleep_for(std::chrono::milliseconds(250));
temperature.update(5);
seer::instant_event("key press", seer::InstantEventScope::thread);
test_helper::get_with_timeout<void>(std::async(std::launch::async, [async, &temperature] {
seer::set_thread_name("input");
const auto timer = async.create_timer("capture keypress");
std::this_thread::sleep_for(std::chrono::seconds(1));
temperature.update(1);
}));
std::this_thread::sleep_for(std::chrono::milliseconds(250));
temperature.update(10);
const auto timer = async.create_timer("process keypress");
std::this_thread::sleep_for(std::chrono::milliseconds(250));
seer::mark("done");
}
temperature.update(4);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
seer::instant_event("sun outside", seer::InstantEventScope::global);
}
seer::buffer.dump_to_file("full-showcase.json");