Проблема в том, что вызов std::this_thread::get_id() оказывается слишком затратным.
В boost::this_thread::get_id() или QThread::currentThreadId() фактически сводятся к GetCurrentThreadId() который в свою очередь сводится к копированию этого поля из TEB.
В std::this_thread::get_id() от Visual Studio 2012 оно сводится к такому:
_Thrd_t _Thrd_current(void)
{ /* return _Thrd_t identifying current thread */
_Thrd_t thr;
#ifdef _WIN32_WCE
thr._Hnd = (HANDLE)GetCurrentThreadId();
#else /* _WIN32_WCE */
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), // <-- вот оно
GetCurrentProcess(), &thr._Hnd,
DUPLICATE_SAME_ACCESS, TRUE, 0))
CloseHandle(thr._Hnd);
else
thr._Hnd = 0;
#endif /* _WIN32_WCE */
thr._Id = GetCurrentThreadId();
return (thr);
}
Соответственно, из-за этого DuplicateHandle вызов std::this_thread::get_id() становится дорогим и ряд оптимизаций, рассчитанных на совпадение текущего thread id с ожидаемым превращаются в пессимизации из-за проверки thread id.
Интересно, какой смысл получения настоящего дескриптора текущей нити, если он закрывается в следующей же строке.
Особенно с учётом того, что дескрипторы достаточно быстро уходят в повторное использование.
UPD: В VS 2015 исправлено.
Приведенная выше _Thrd_current() осталась, но для std::this_thread::get_id() она не вызывается, вызывается _Thrd_id(), которая просто вызывает GetCurrentThreadId().