[C++]시간측정

안민기·2024년 12월 22일

개요

나는 더 나은 코드를 위해선 공간/시간 복잡도를 중요시 여기는데,
특히 실업무에선 시간 복잡도가 더 중요한 것 같다.
자원 효율성은 드라마틱하지 않아서 묻히는 경향이 있는 것 같다.. + HW성능이 너무 좋아

따라서 앞으로 내가 어디서든 필요한 코드를 이 블로그에 wiki처럼 저장해두려 한다.
(더 나아가서 git에 저장해서 언제든 clone해서 쓰는게 최종목표)

시간측정 코드는 매우 간단하다.
chrono라는 정밀한 시간측정 라이브러리가 있기 때문이다.
따라서 나는 함수단위 측정 코드와 블럭단위 측정 코드를 분리했다.

목표는 크게 두가지이다.
첫째. 시간측정 코드 재활용
둘째. 추후 template 및 Args 활용(C++에 유용한 기능이 이렇게 많은 줄 몰랐음)

함수단위 시간측정

이 코드는 두가지 case를 고려한다.
반환값이 있는 함수, 반환값이 없는 함수.
이유는 auto를 사용하여 적절한 자료형으로 반환할 수 있지만, void의 경우는 return자체를 못하기 때문임.

이를 위해 또 두가지의 포인트가 있다.
첫째. 반환 타입 추론(decltype)
- decltype(...)은 컴파일 시 표현식의 타입을 추론한다.
따라서 void의 경우는 !연산을 통해 조건문을 사용할 수 있다.

둘째. 템플릿(template)
- 템플릿은 추후 자세히 다뤄야 함(포스트 작성 시 삭제)
템플릿은 함수 정의 앞에 위치해야 하며 어떤 타입의 함수가 호출될 지 알 수 있다.
컴파일러는 컴파일 시 템플릿 함수의 매개변수를 구체화 한다.
즉, 아래에서는 typename 뒤의 Func와 Args의 타입을 구체화 함!
(추후 사실 확인 시 삭제 바람 - 함수의 매개변수는 자료형이 있어야 함.
void func(auto a); 같이 매개변수가 auto일 순 없음.
따라서 매개변수를 auto로 쓰고 싶으면 템플릿
자료형 반환 auto는 템플릿과 무관하지만 유동적으로 사용하기 좋음)

// measureTime.h

#pragma once
#include <iostream>
#include <chrono>

// 함수 실행시간 측정
template <typename Func, typename... Args>
auto measureExecutionTime(Func&& func, Args&&... args) 
-> decltype(std::forward<Func>(func)(std::forward<Args>(args)...)) {
    auto start = std::chrono::high_resolution_clock::now(); // 시작시간

    // 반환값이 있는 함수일 경우
    if constexpr (!std::is_void_v<decltype(std::forward<Func>(func)(std::forward<Args>(args)...))>) {
        // 함수 호출 및 반환값 캡처
        auto result = std::forward<Func>(func)(std::forward<Args>(args)...);

        // 종료 시간 기록
        auto end = std::chrono::high_resolution_clock::now(); // 종료시간

        // 실행 시간 계산
        std::chrono::duration<double> duration = end - start; // 시간측정
        std::cout << "Function execution time: " << duration.count() << " seconds\n\n";

        // 반환값 리턴
        return result;
    }
    // 반환값이 void인 함수일 경우
    else {
        std::forward<Func>(func)(std::forward<Args>(args)...);  // 함수 호출

        // 종료 시간 기록
        auto end = std::chrono::high_resolution_clock::now(); // 종료시간

        // 실행 시간 계산
        std::chrono::duration<double> duration = end - start; // 시간측정
        std::cout << "Function execution time: " << duration.count() << " seconds\n\n";
    }
}

블럭단위 시간측정

// measureTime.h
#pragma once
#include <iostream>
#include <chrono>

// 블럭 실행시간 측정
template <typename Func>
void measureBlockTime(Func&& func) {
    auto start = std::chrono::high_resolution_clock::now(); // 시작시간

    std::forward<Func>(func)(); // 블럭 실행

    auto end = std::chrono::high_resolution_clock::now();   // 종료시간

    std::chrono::duration<double> duration = end - start;   // 시간측정
    std::cout << "Block execution time: " << duration.count() << " seconds\n\n";
}

main함수

// main함수

int main() {
    {
        cout << "void 함수 수행시간 측정" << endl;
        measureExecutionTime(func1, vecSize);
    }

    {
        cout << "non-void 함수 수행시간 측정" << endl;
        vector<int64_t> vec = measureExecutionTime(func2, vecSize);
    }
    
    {
        cout << "블럭 수행시간 측정" << endl;
        measureBlockTime([]() {
            int64_t _vecSize = vecSize;
            vector<int64_t> vec(_vecSize);
            for (size_t idx = 0; idx < _vecSize; idx++)
                vec[idx] = idx;
            cout << "vec.size: " << vec.size() << endl;
            });
    }
}

결과

profile
Trendy AI Developer

0개의 댓글