У меня есть функция, которая берет список символов и генерирует следующую лексикографическую перестановку. Ради интереса я попытался обобщить код для использования итераторов, а также для возможности генерировать перестановки более разных типов.
template<typename ITER>
bool nextPermutation(ITER start, ITER end, std::random_access_iterator_tag)
{
for(ITER i = end-1; i != start; --i)
{
if(*(i-1) < *i)
{
// found where can be swapped
for(ITER j = end-1; j != (i-1); --j)
{
if(*(i-1) < *j)
{
// found what to swap with
auto temp = *j;
*j = *(i-1);
*(i-1) = temp;
// put everything from i on into "sorted" order by reversing
for(ITER k = end-1; k > i; --k,++i)
{
temp = *k;
*k = *i;
*i = temp;
}
return true;
}
}
}
}
return false;
}
Однако у меня возникают проблемы, когда без использования необработанных указателей производительность кода значительно снижается. Вот мой испытательный стенд:
template<typename ITER>
bool nextPermutation(ITER start, ITER end, std::random_access_iterator_tag);
template<typename ITER>
bool nextPermutation(ITER start, ITER end)
{
return nextPermutation(start, end, std::iterator_traits<ITER>::iterator_category());
}
#define USE_VECTOR
int main(void)
{
bool hasNext = true;
#ifdef USE_VECTOR
std::vector<char> c;
for(char i = '0'; i <= '9'; ++i)
{
c.push_back(i);
}
for(size_t i = 0; i < 999999 && hasNext; ++i)
{
hasNext = nextPermutation(c.begin(), c.end());
}
#else
char c[] = "0123456789";
size_t LENGTH = 10;
for(size_t i = 0; i < 999999 && hasNext; ++i)
{
hasNext = nextPermutation(c, c+LENGTH);
}
#endif
std::cout << "done" << std::endl;
std::cin.ignore();
return 0;
}
Когда определено USE_VECTOR
, запуск этой испытательной установки занимает ~ 20 секунд. Когда я определяю его, коды запускаются менее чем за секунду (я не писал никакого временного кода, но достаточно сказать, что есть очень существенная разница в производительности).
Теперь мой вопрос: где я получаю такой огромный удар по производительности, который может повлиять на использование итератора (итератор std :: string, итератор std :: vector и т. Д.) И необработанного указателя?