Medir o tempo de execução de uma função em C++ STL

Jinku Hu 12 outubro 2023
  1. Use std::chrono::high_resolution_clock::now e std::chrono::duration_cast<std::chrono::seconds> para medir o tempo de execução de uma função
  2. Use std::chrono::high_resolution_clock::now e std::chrono::duration<double, std::milli> para medir o tempo de execução de uma função
Medir o tempo de execução de uma função em C++ STL

Este artigo demonstrará vários métodos sobre como medir o tempo de execução de uma função em C++.

Use std::chrono::high_resolution_clock::now e std::chrono::duration_cast<std::chrono::seconds> para medir o tempo de execução de uma função

O namespace std::chrono consolida todos os utilitários de data e hora fornecidos pela biblioteca C++ STL. O último oferece várias implementações de relógio, uma das quais é std::chrono::high_resolution_clock que corresponde ao relógio com o menor período de tique. Observe, porém, que este relógio depende da plataforma de hardware e até mesmo várias implementações de biblioteca padrão diferem, portanto, é melhor ler a documentação do compilador e certificar-se de que este seja adequado para os requisitos do problema. A ideia para medir o tempo de execução de uma função é recuperar a hora atual do relógio dado duas vezes: antes e depois da chamada da função, e calcular a diferença entre os valores. A hora atual é recuperada usando o método embutido now. Uma vez calculada a diferença, ela deve ser interpretada em uma determinada unidade de tempo, o que é feito usando o utilitário std::chrono::duration_cast. No exemplo a seguir, lançamos o resultado em unidades std::chrono::seconds e geramos o valor com a função embutida count. Observe que o funcSleep no exemplo de código suspende a execução do programa por 3 segundos e então retorna o controle para a função main.

#include <chrono>
#include <iostream>
#include <thread>

using std::cout;
using std::endl;

void funcSleep() { std::this_thread::sleep_for(std::chrono::seconds(3)); }

int main() {
  auto start = std::chrono::high_resolution_clock::now();
  funcSleep();
  auto end = std::chrono::high_resolution_clock::now();

  auto int_s = std::chrono::duration_cast<std::chrono::seconds>(end - start);

  std::cout << "funcSleep() elapsed time is " << int_s.count() << " seconds )"
            << std::endl;

  return EXIT_SUCCESS;
}

Resultado:

funcSleep() elapsed time is 3 seconds

Use std::chrono::high_resolution_clock::now e std::chrono::duration<double, std::milli> para medir o tempo de execução de uma função

Em contraste com o código anterior, onde a unidade de tempo foi salva em um valor inteiro, o próximo exemplo armazena o valor do intervalo como um número de ponto flutuante no std::chrono::duration<double, std::milli> tipo de objeto. std::chrono::duration é um modelo de classe geral para representar o intervalo de tempo. Finalmente, o valor do intervalo é recuperado usando a função count, em cujo ponto ele pode ser impresso no fluxo cout.

#include <chrono>
#include <iostream>
#include <thread>

using std::cout;
using std::endl;

void funcSleep() { std::this_thread::sleep_for(std::chrono::seconds(3)); }

int main() {
  auto start = std::chrono::high_resolution_clock::now();
  funcSleep();
  auto end = std::chrono::high_resolution_clock::now();

  std::chrono::duration<double, std::milli> float_ms = end - start;

  std::cout << "funcSleep() elapsed time is " << float_ms.count()
            << " milliseconds" << std::endl;

  return EXIT_SUCCESS;
}

Resultado:

funcSleep() elapsed time is 3000.27 milliseconds

Os dois últimos exemplos mediram uma função que geralmente leva tempo constante, mas uma abordagem semelhante pode ser usada para calcular o tempo de execução do bloco de código fornecido. Como exemplo, o fragmento a seguir demonstra a função de geração aleatória de inteiros que leva mais intervalos variáveis ​​para ser executada. Observe que, desta vez, usamos os dois métodos para exibir o tempo com precisão de milissegundos e segundos.

#include <chrono>
#include <iostream>
#include <thread>

using std::cout;
using std::endl;

constexpr int WIDTH = 1000000;

void generateNumbers(int arr[]) {
  std::srand(std::time(nullptr));
  for (size_t i = 0; i < WIDTH; i++) {
    arr[i] = std::rand();
  }
}

int main() {
  int *arr = new int[WIDTH];

  auto start = std::chrono::high_resolution_clock::now();
  generateNumbers(arr);
  auto end = std::chrono::high_resolution_clock::now();

  std::chrono::duration<double, std::milli> float_ms = end - start;
  auto int_ms =
      std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::chrono::duration<long, std::micro> int_usec = int_ms;

  std::cout << "generateNumbers() elapsed time is " << float_ms.count()
            << " ms "
            << "( " << int_ms.count() << " milliseconds )" << std::endl;

  delete[] arr;
  return EXIT_SUCCESS;
}

Resultado:

generateNumbers() elapsed time is 30.7443 ms ( 30 milliseconds )
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artigo relacionado - C++ Time