2009-10-20 22:32:53 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* This file is part of Mapnik (c++ mapping toolkit)
|
|
|
|
*
|
2011-09-01 03:06:33 +02:00
|
|
|
* Copyright (C) 2011 Artem Pavlenko
|
2009-10-20 22:32:53 +02:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2011-10-23 16:09:47 +02:00
|
|
|
#ifndef MAPNIK_TIMER_HPP
|
|
|
|
#define MAPNIK_TIMER_HPP
|
2009-10-20 22:32:53 +02:00
|
|
|
|
2011-10-23 16:09:47 +02:00
|
|
|
// stl
|
2009-12-16 21:02:06 +01:00
|
|
|
#include <cstdlib>
|
2011-08-25 00:02:07 +02:00
|
|
|
#include <string>
|
2011-09-01 06:48:09 +02:00
|
|
|
#include <sstream>
|
|
|
|
#include <iomanip>
|
2011-11-10 01:41:07 +01:00
|
|
|
#include <ctime>
|
2009-12-14 00:30:36 +01:00
|
|
|
|
2009-10-20 22:32:53 +02:00
|
|
|
namespace mapnik {
|
|
|
|
|
2011-09-01 03:06:33 +02:00
|
|
|
// Measure times in both wall clock time and CPU times. Results are returned in milliseconds.
|
|
|
|
class timer
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2011-09-01 03:06:33 +02:00
|
|
|
timer()
|
|
|
|
{
|
|
|
|
restart();
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2009-10-20 22:32:53 +02:00
|
|
|
|
2010-06-02 13:03:30 +02:00
|
|
|
void restart()
|
|
|
|
{
|
2011-09-01 06:33:39 +02:00
|
|
|
_stopped = false;
|
2011-09-01 03:06:33 +02:00
|
|
|
gettimeofday(&_wall_clock_start, NULL);
|
|
|
|
_cpu_start = clock();
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2009-10-20 22:32:53 +02:00
|
|
|
|
2011-09-01 06:33:39 +02:00
|
|
|
virtual void stop() const
|
2011-09-01 03:06:33 +02:00
|
|
|
{
|
2011-09-01 06:33:39 +02:00
|
|
|
_stopped = true;
|
2011-09-01 03:06:33 +02:00
|
|
|
_cpu_end = clock();
|
|
|
|
gettimeofday(&_wall_clock_end, NULL);
|
|
|
|
}
|
2009-10-20 22:32:53 +02:00
|
|
|
|
2011-09-01 03:06:33 +02:00
|
|
|
double cpu_elapsed() const
|
|
|
|
{
|
|
|
|
// return elapsed CPU time in ms
|
2011-09-01 06:33:39 +02:00
|
|
|
if (!_stopped)
|
2011-09-01 03:06:33 +02:00
|
|
|
stop();
|
|
|
|
|
|
|
|
return ((double) (_cpu_end - _cpu_start)) / CLOCKS_PER_SEC * 1000.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
double wall_clock_elapsed() const
|
|
|
|
{
|
|
|
|
// return elapsed wall clock time in ms
|
2011-09-01 06:33:39 +02:00
|
|
|
if (!_stopped)
|
2011-09-01 03:06:33 +02:00
|
|
|
stop();
|
|
|
|
|
|
|
|
long seconds = _wall_clock_end.tv_sec - _wall_clock_start.tv_sec;
|
|
|
|
long useconds = _wall_clock_end.tv_usec - _wall_clock_start.tv_usec;
|
2009-10-20 22:32:53 +02:00
|
|
|
|
2010-06-02 13:03:30 +02:00
|
|
|
return ((seconds) * 1000 + useconds / 1000.0) + 0.5;
|
|
|
|
}
|
2011-09-01 06:33:39 +02:00
|
|
|
protected:
|
|
|
|
mutable timeval _wall_clock_start, _wall_clock_end;
|
|
|
|
mutable clock_t _cpu_start, _cpu_end;
|
|
|
|
mutable bool _stopped;
|
2010-06-02 13:03:30 +02:00
|
|
|
};
|
2009-10-20 22:32:53 +02:00
|
|
|
|
2010-06-02 13:03:30 +02:00
|
|
|
// A progress_timer behaves like a timer except that the destructor displays
|
|
|
|
// an elapsed time message at an appropriate place in an appropriate form.
|
2011-09-01 03:06:33 +02:00
|
|
|
class progress_timer : public timer
|
2010-06-02 13:03:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2011-09-01 03:06:33 +02:00
|
|
|
progress_timer(std::ostream & os, std::string const& base_message):
|
2011-08-25 00:02:07 +02:00
|
|
|
os_(os),
|
2011-09-01 06:33:39 +02:00
|
|
|
base_message_(base_message)
|
|
|
|
{}
|
2011-08-25 00:02:07 +02:00
|
|
|
|
2011-09-01 03:06:33 +02:00
|
|
|
~progress_timer()
|
2009-10-20 22:32:53 +02:00
|
|
|
{
|
2011-09-01 06:33:39 +02:00
|
|
|
if (!_stopped)
|
2011-08-25 00:02:07 +02:00
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
2011-09-01 06:33:39 +02:00
|
|
|
void stop() const
|
|
|
|
{
|
2011-09-01 03:06:33 +02:00
|
|
|
timer::stop();
|
2010-06-02 13:03:30 +02:00
|
|
|
try
|
2009-10-20 22:32:53 +02:00
|
|
|
{
|
2011-08-25 00:02:07 +02:00
|
|
|
std::ostringstream s;
|
|
|
|
s.precision(2);
|
|
|
|
s << std::fixed;
|
2011-09-01 06:33:39 +02:00
|
|
|
s << wall_clock_elapsed() << "ms (cpu " << cpu_elapsed() << "ms)";
|
2011-09-01 03:06:33 +02:00
|
|
|
s << std::setw(30 - (int)s.tellp()) << std::right << "| " << base_message_ << "\n";
|
2011-08-25 00:02:07 +02:00
|
|
|
os_ << s.str();
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
|
|
|
catch (...) {} // eat any exceptions
|
2011-08-25 01:15:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void discard() {
|
2011-09-01 06:33:39 +02:00
|
|
|
_stopped = true;
|
2010-06-02 13:03:30 +02:00
|
|
|
}
|
2009-10-20 22:32:53 +02:00
|
|
|
|
2010-06-02 13:03:30 +02:00
|
|
|
private:
|
2011-08-25 00:02:07 +02:00
|
|
|
std::ostream & os_;
|
|
|
|
std::string base_message_;
|
2010-06-02 13:03:30 +02:00
|
|
|
};
|
2009-10-20 22:32:53 +02:00
|
|
|
|
|
|
|
};
|
2011-10-23 16:09:47 +02:00
|
|
|
#endif // MAPNIK_TIMER_HPP
|