Profiler class, suggestions and comments welcome
Hi everybody,
with this very post I'm starting my first thread into this NG.
I know that my behavior so far has been a bit uncommon. It's uncommon
to drop into a technical NG and start giving comments and advices
before asking for comments and advices in first place - even more if
the person doing it is a hobbyist like me.
I hope you'll be so kind to step over the above mentioned facts and
comment my code without any kind of prejudgment.
So then, here is the point.
I lack the knowledge to properly use debuggers and profilers that come
with Code::Blocks. Actually, I'm not even sure about whether it
includes a profiler... never mind.
Hence, I usually debug my code by printing out variable values to the
console and the alike.
About measuring the performance of my code, I used functions like
"StartTimer(string timername)" and "StopTimer(string timername)".
After a short while I got tired of calling such functions at the begin
and at the end of the functions I was profiling - along with having to
recall the string IDs or creating local strings to avoid recalling
them.
Hence I created a profiler class that automatically logs the start/
stop times upon construction/destruction.
Here is my profiler class. A couple of questions right after it:
-------
// combining header and implementation for easy copy&paste
// header (double-inclusion check snipped out)
#include <string>
namespace profiler {
class Profile {
public:
Profile(std::string = "");
~Profile();
private:
std::string id;
};
std::string report();
}
// implementation
#include <ctime>
#include <map>
#include <sstream>
// profiler's header inclusion snipped
struct time_pair {
clock_t start;
clock_t stop;
};
typedef std::map<std::string, time_pair> time_map_type;
time_map_type time_map;
profiler::Profile::Profile(std::string s) {
id = s;
clock_t& rct = time_map[id].start;
rct = clock();
}
profiler::Profile::~Profile() {
clock_t ct = clock();
time_map[id].stop = ct;
}
std::string profiler::report() {
time_map_type::const_iterator iter;
std::stringstream res;
for(iter = time_map.begin(); iter != time_map.end(); ++iter) {
res << iter->first << "\n" << "Start: ";
res << iter->second.start << ", stop: ";
res << iter->second.stop << ", total: ";
res << (iter->second.stop - iter->second.start) << "\n";
}
return res.str();
}
-------
I use it in this way:
-------
void f() {
profiler::Profile p("f()");
// ... code to be profiled ...
}
-------
And here are the questions:
- Why must I set "~Profile()" as public? (apart from the fact that the
compiler refuses to compile it if I set it to private or protected)
Shouldn't it be something to be left out from the public interface so
that users can not mess with it? <--- academic question, I don't have
such issues (unfortunately...)
- Notice how I used an additional variable and a reference to avoid
including the map lookup time into the logged time, in the ctor and
the dtor. Is this a smart move or is it just paranoia?
I don't have any other specific question about this very simple piece
of code, nonetheless I'll be happy to read your comments and your
advices on any subject - naming style included.
Some time later I'll ask for your advice about something more
interesting (more interesting to me: a simulation of ants harvesting
food around their nest). I'm not so sure, though. It will involve
posting the SDL interface code, asking questions about generic OOP and
about ants' behavior, hence I'm not sure this will be the right place
to post it - assuming I'll be ever brave enough to show my
"abomination" to the world ;-)
Thank you for your attention,
best regards,
Francesco