C# では、Stopwatch クラスを起動して、特定のメソッドにかかる時間をすばやく正確に計測します。
C ++でこれに相当するものは何ですか? 高精度タイマーは内蔵されていますか?
操作の継続時間を測定するためにboost::timerを使用しました。これは、測定を行うための非常に簡単な方法を提供すると同時に、プラットフォームに依存しません。次に例を示します。
boost::timer myTimer;
doOperation();
std::cout << myTimer.elapsed();
PS精度の誤差を克服するには、数秒かかる操作を測定するのがよいでしょう。特に、いくつかの選択肢を比較しようとしている場合。時間がかからないものを測定したい場合は、ループに入れてみてください。たとえば、操作を1000回実行してから、合計時間を1000で割ります。
以前にこのような状況でタイマーを実装したことがあります。実際には、Windows 用と POSIX 用の 2 つの異なる実装を持つクラスになりました。
その理由は、Windows には、QueryPerformanceCounter()
このようなタイミングに最適な非常に正確なクロックにアクセスできる機能があるためです。
ただし、POSIXではこれは利用できないため、boost.datetimeのクラスを使用して開始時刻と終了時刻を保存し、それらから期間を計算しました。「高解像度」タイマーを提供しますが、解像度は未定義であり、プラットフォームごとに異なります。
私は独自のバージョンの Python のtime_it
関数を使用しています。この関数の利点は、意味のある結果を得るために必要な回数だけ計算を繰り返すことです。計算が非常に高速な場合、何度も繰り返されます。最後に、すべての繰り返しの平均時間を取得します。非標準の機能は使用しません。
#include <ctime>
double clock_diff_to_sec(long clock_diff)
{
return double(clock_diff) / CLOCKS_PER_SEC;
}
template<class Proc>
double time_it(Proc proc, int N=1) // returns time in microseconds
{
std::clock_t const start = std::clock();
for(int i = 0; i < N; ++i)
proc();
std::clock_t const end = std::clock();
if(clock_diff_to_sec(end - start) < .2)
return time_it(proc, N * 5);
return clock_diff_to_sec(end - start) * (1e6 / N);
}
次の例では、time_it
関数を使用して、さまざまな STL コンテナーのパフォーマンスを測定しています。
void dummy_op(int i)
{
if(i == -1)
std::cout << i << "\n";
}
template<class Container>
void test(Container const & c)
{
std::for_each(c.begin(), c.end(), &dummy_op);
}
template<class OutIt>
void init(OutIt it)
{
for(int i = 0; i < 1000; ++i)
*it = i;
}
int main( int argc, char ** argv )
{
{
std::vector<int> c;
init(std::back_inserter(c));
std::cout << "vector: "
<< time_it(boost::bind(&test<std::vector<int> >, c)) << "\n";
}
{
std::list<int> c;
init(std::back_inserter(c));
std::cout << "list: "
<< time_it(boost::bind(&test<std::list<int> >, c)) << "\n";
}
{
std::deque<int> c;
init(std::back_inserter(c));
std::cout << "deque: "
<< time_it(boost::bind(&test<std::deque<int> >, c)) << "\n";
}
{
std::set<int> c;
init(std::inserter(c, c.begin()));
std::cout << "set: "
<< time_it(boost::bind(&test<std::set<int> >, c)) << "\n";
}
{
std::tr1::unordered_set<int> c;
init(std::inserter(c, c.begin()));
std::cout << "unordered_set: "
<< time_it(boost::bind(&test<std::tr1::unordered_set<int> >, c)) << "\n";
}
}
誰かが興味を持っている場合、ここに私が得た出力があります(リリースモードでVS2008でコンパイルされています):
ベクトル: 8.7168
リスト: 27.776
デキュー: 91.52
セット: 103.04
unordered_set: 29.76
You can use the ctime library to get the time in seconds. Getting the time in milliseconds is implementation-specific. Here is a discussion exploring some ways to do that.
High-precision timers are platform-specific and so aren't specified by the C++ standard, but there are libraries available. See this question for a discussion.
これは、言語の問題ではなく、OS に依存する問題である可能性があります。
Windows を使用している場合は、GetTickCount()または GetTickCount64()を使用して、 10 ~ 16 ミリ秒のミリ秒タイマーにアクセスできます。最初に 1 回、最後に 1 回呼び出して、減算するだけです。
私の記憶が正しければ、それは私が以前に使用したものでした。リンクされたページには、他のオプションもあります。
このクラスは便利です。
RAII イディオムを使用して、デストラクタが呼び出されたときに構造で指定されたテキストを出力し、経過時間のプレースホルダーを適切な値で埋めます。
使用例:
int main()
{
trace_elapsed_time t("Elapsed time: %ts.\n");
usleep(1.005 * 1e6);
}
出力:
Elapsed time: 1.00509s.
#include <time.h>
clock_t start, end;
start = clock();
//Do stuff
end = clock();
printf("Took: %f\n", (float)((end - start) / (float)CLOCKS_PER_SEC));