Sleepとsleep_for

こんにちは!!
くろんです

今回はWindowsにてC++で処理を待たせる関数、Sleep()とstd::this_thread::sleep_for()の違いについて考えたいと思います。

先に結論を
- C++11にて追加されているので、現在の標準はこっち?
- ナノ秒での指定ができるので精度が高い
- 時間でも指定ができるので最大指定時間も大きい

Sleep()はWindowsAPIにある関数になります。

使用すると指定された相対時間分、現在のスレッドを止めてくれます。
指定はmillisecondsなので1000分の1秒にて指定ができます。

sleep_for()はC++11にて追加された関数です。

こちらもSleep()同様に指定された相対時間分、現在のスレッドを止めます。
こちらはSleep()とは異なりnanosecondsまで指定ができます。

milliseconds = 1 / 1000 秒
microseconds = 1 / 1000 milliseconds
nanoseconds = 1 / 1000 microseconds

なのでsleep_for()はSleep()の100万分の1の精度で指定できることになります。

100万分の1の精度で指定できるということはなんか色々性能が高そうな感じがしたので、実際のコードで測定をしてみました。

以下、検証コード

#include <chrono>
#include <thread>
#include <Windows.h>

void winSleepLoop(int waitMilliseconds, int loopTimes)
{
	for(int i = 0; i < loopTimes; i++) {
		Sleep(static_cast<DWORD>(waitMilliseconds));
	}
}

void threadSleepLoop(int waitNanoseconds, int loopTimes)
{
	for(int i = 0; i < loopTimes; i++) {
		std::chrono::nanoseconds ns(waitNanoseconds);
		std::this_thread::sleep_for(ns);
	}
}

int main(int argc, char* argv[])
{
	LARGE_INTEGER freq;
	QueryPerformanceFrequency(&freq);

	LARGE_INTEGER start, end;
	QueryPerformanceCounter(&start);

	// wait time(milli sec)
	winSleepLoop(100, 100);

	QueryPerformanceCounter(&end);

	double duration = (end.QuadPart - start.QuadPart)
						/ static_cast<double>(freq.QuadPart);
	printf("winSleep = %f\n", duration);

	QueryPerformanceCounter(&start);

	// wait time(nano sec)
	threadSleepLoop(100000000, 100);

	QueryPerformanceCounter(&end);
	
	duration = (end.QuadPart - start.QuadPart)
				/ static_cast<double>(freq.QuadPart);
	printf("threadSleep = %f\n", duration);

	return 0;
}

検証結果

winSleep = 10.057575
threadSleep = 10.049585

検証結果…まったく変わりませんでした!!

結果はあまり変わらなかったということで処理性能的にはどっちを選んでも大丈夫そうですね。

少しくらい誤差でるかなと思っていたので残念です。

ちなみにSleepでは時間をDWORDで指定するのですが、こちらはunsigned longで定義されているので数値範囲は 0 ~ 4,294,967,295 となります。
maxの数値は日数で表すと約50日分になります。

なので、Sleep()一つでは50日以上処理を待たせることができません。待たせる必要があるのかという素朴な疑問は置いておきますが…

ただ、sleep_for()ではchronoで定義されている型を使用して時間での指定ができるので、50日以上待たせることが可能となります!!

以上を踏まえてsleep_for()を使うメリットはこんな感じですかね。

  • C++11にて追加されているので、現在の標準はこっち?
  • ナノ秒での指定ができるので精度が高い
  • 時間でも指定ができるので最大指定時間も大きい

まぁ、面倒でなければC++で書くのはsleep_for()のほうがいいかと思います。

では

投稿者: くろん

GitHub: https://github.com/ckron

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください