timeExternal = 0,008407 с против timeInternal = 0,004287 У нас есть соотношение 1,96105 между двумя ..
Ожидается соотношение ~ 2 - безусловно, самый тяжелый вызов вВаш цикл clock()
(в большинстве систем clock()
является системным вызовом ядра).
Представьте, что реализация clock()
выглядит следующим образом псевдокод :
clock_t clock() {
go_to_kernel(); // very long operation
clock_t rc = query_process_clock();
return_from_kernel(); // very long operation
return rc;
}
Теперь, возвращаясь к циклу, мы можем комментировать места, где тратится время:
for(int i=0;i<10000;i++){
// go_to_kernel - very long operation
clockStartLoop = clock();
// return_from_kernel - very long operation
vecInt.push_back(i);
// go_to_kernel - very long operation
timeInternal += clock() - clockStartLoop;
// return_from_kernel - very long operation
}
Таким образом, между двумя вызовами на clock()
у нас есть 2 длинные операции с общим количеством вцикл 4. Следовательно, отношение 2 к 1.
- Это только потому, что существуют операции внутри цикла, которые не измеряются разницей
clock()
(такойкак увеличение timeInternal
)?
Нет, увеличение timeInterval
незначительно.
- Может ли операция
i++
в for(..)
быть не пренебрежимо малым во внешнем измерении, а также объяснить разницу с внутренним измерением?
Нет, i++
также незначительно. Удалите внутренние вызовы на clock()
, и вы увидите намного более быстрое время выполнения. В моей системе это было 0,00003 с.
Следующая самая дорогая операция после clock()
- vector::push_back()
, потому что ей нужно изменить размер vector
. Это амортизируется квадратичным фактором роста и может быть полностью устранено путем вызова vector::reserve()
перед входом в цикл.
Вывод: при тестировании обязательно синхронизируйте целые циклы, а не отдельные итерации. А еще лучше - использовать фреймворки, такие как Google Benchmark , которые помогут избежать многих других ловушек (например, оптимизации компилятора). Также есть quick-bench.com для простых случаев (на основе Google Benchmark).