Commit a7330f10 authored by Pádraig Ó Conbhuí's avatar Pádraig Ó Conbhuí
Browse files

Improve README.md

parent 2291cd22
Perforate PERForate
========= =========
A low-overhead C++ scope timing utility. A low-overhead C++ scope timing utility.
Summary
---------
PERForate is a tiny performance measurement library.
The idea is to include one header, and drop `PERFORATE_SCOPE_TRACE("my text")`
into a function, and have some measurement of its execution time printed after
the program exits.
This gets around a lot of issues wrt compiler optimizations inlining some
functions, omitting symbols, finding the right incantation for the compiler on
your system, and getting all that working with a performance tool.
Each call to `PERFORATE_SCOPE_TRACE` has about 100 ns overhead, so it can mostly
be dropped in and ignored anywhere except for hot-loops.
This nicely works across MacOS and Linux, with Clang and GCC, and locally and
remotely.
No special configurations, no debug symbols, no compiler flags, no
post-processing tools, no magic, no tearing your hair out.
It works the same on low and high optimization settings.
The primary downside is intrusive tracing means you need to modify your code.
But let's be honest, when you're tracking down a performance bug, you're going
to be modifying your code.
Think of it like `printf` debugging, but for time.
The nature of scoped tracing means the scope it's tracing is a basic block, and
can't be merged into other basic blocks during inlining.
This can mess up optimizations that come from inlining.
Example
---------
The following example demonstrates how to time a simple program:
``` cpp
#include <perforate/scoped_trace.hpp>
#include <vector>
int main(int argc, char **argv) {
PERFORATE_SCOPED_TRACE("my program");
std::vector<int> v;
for (int i = 0; i < 100; ++i) {
v.push_back(i);
}
return 0;
}
```
Compiling the code as `g++ main.cpp -O3 -I /path/to/perforate` and then running
will result in an output similar to the following:
```
------------
Range Stats:
------------
my program: 9.288e-06 s, 9.288e-06 s/call, 1 call(s)
------------
```
For a more complex example:
``` cpp
#include <perforate/scoped_trace.hpp>
#include <numeric>
#include <vector>
bool do_something() {
// Measures the entire do_something function
PERFORATE_SCOPED_TRACE("do_something");
// Measure the total time spent in the loop, and gather the time per
// iteration
auto loop_trace = PERFORATE_SCOPED_TRACE_V("do_something::loop").call_count(0);
// Just some busy work that won't get optimized away...
std::vector<int> v;
for(int i=0; i<100000; i++) {
v.push_back(i);
// each ++loop_trace increases the call count without re-initializing
// the scoped_trace.
++loop_trace;
}
// end the scope of loop_trace early, before the end of the block
perforate::end_scoped_trace(std::move(loop_trace));
const int acc = std::accumulate(v.cbegin(), v.cend(), int(0));
return acc % 2 == 1;
}
int main() {
// Measure the whole program
PERFORATE_SCOPED_TRACE("my program");
for(int i=0; i<1000; i++) {
if(do_something()) {
return 1;
}
}
return 0;
}
```
Will generate the output
```
----------------
PERForate Stats:
----------------
my program: 0.118204 s, 0.118204 s/call, 1 call(s)
do_something: 0.11815 s, 0.00011815 s/call, 1000 call(s)
do_something::loop: 0.107854 s, 1.07854e-09 s/call, 100000000 call(s)
----------------
```
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment