[備忘録] C/C++コードのある区間の所要時間を求めたい(Windows/Linux両対応)

# 時間測定ライブラリ

このプロジェクトは、Windows、Linux、macOS に対応した **高精度な時間測定ライブラリ** です。  
Windowsでは `QueryPerformanceCounter()`、Linux/macOSでは `clock_gettime()` を利用し、ナノ秒単位の精度で実行時間を測定できます。

## **ソースコード**
get_time.h (計測対象のソースにこれをインクルード):
```c
#pragma once
#ifndef H_GET_TIME_H__
#define H_GET_TIME_H__
#endif

#include <stdio.h>
#include <stdint.h>

#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#endif

#ifdef _WIN32
double get_time(void) {
    static LARGE_INTEGER freq;
    static int initialized = 0;
    if (!initialized) {
        QueryPerformanceFrequency(&freq);
        initialized = 1;
    }

    LARGE_INTEGER now;
    QueryPerformanceCounter(&now);
    return (double)now.QuadPart / freq.QuadPart;
}
#else
double get_time(void) {
    struct timespec ts;
#ifdef CLOCK_MONOTONIC_RAW
    clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
#else
    clock_gettime(CLOCK_MONOTONIC, &ts);
#endif
    return ts.tv_sec + ts.tv_nsec / 1e9;
}

#endif
```
main.c (使い方サンプル):
```c
#include <stdio.h>
#include <stdint.h>

#include "get_time.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#endif

int main(void) {
    double start = get_time(); // ↓この区間の所要時間を計測したいとします。
    for (volatile int i = 0; i < 99999; i++) {}
    double end = get_time();   // ↑この区間の所要時間を計測したいとします。

    printf("所要時間: %.9f 秒。\n", end - start);

    return 0;
}
```

## **機能**
- ✅ **クロスプラットフォーム対応** (Windows / Linux / macOS)
- ✅ **高精度な時間測定** (ナノ秒単位です)
- ✅ **シンプルな API** (`get_time()` を呼び出すだけです)
- ✅ **低オーバーヘッド** (パフォーマンスへの影響が最小限度だと思います)

## **ファイル構成**
| ファイル名       | 説明 |
|----------------|--------------------------------------------|
| `get_time.h`   | 高精度時間測定関数 `get_time()` を定義するヘッダーファイル |
| `main.c`       | `get_time()` を使用して実行時間を測定するサンプルプログラム |

## **技術解説**
このライブラリでは、各プラットフォームに応じた高精度なシステム関数を使用しています。

### **1. Windows の時間測定**
Windows では `QueryPerformanceCounter()` を使用し、高精度なタイムスタンプを取得します。

#### **測定方法**
1. `QueryPerformanceFrequency()` を呼び出し、1秒あたりのカウント数を取得します。
2. `QueryPerformanceCounter()` で現在のカウンタ値を取得します。
3. カウント値を周波数で割ることで、秒単位の時刻を計算します。

計算式:
```c
(double)now.QuadPart / freq.QuadPart
```

### **2. Linux/macOS の時間測定**
Linux および macOS では `clock_gettime()` を使用し、ナノ秒単位の高精度な時刻を取得します。

#### **測定方法**
1. `clock_gettime(CLOCK_MONOTONIC, &ts)` で現在の時刻を取得します。
2. `ts.tv_sec` (秒) と `ts.tv_nsec` (ナノ秒) を結合し、秒単位の時間を計算します。

計算式:
```c
ts.tv_sec + ts.tv_nsec / 1e9
```

`CLOCK_MONOTONIC_RAW`が使用できる場合はカーネルの補正がない生の時間を取得し、より正確な測定が可能です。

## **使用方法**
### **1. コンパイル**
#### **Linux/macOS**
以下のコマンドでコンパイルし実行できます。
```sh
gcc -o main main.c -lrt
./main
```
(*注:* `-lrt` は `clock_gettime()` のリンクに必要な場合があります。)

#### **Windows (MinGW)**
```sh
gcc -o main.exe main.c -O2
main.exe
```

#### **Windows (Visual Studio)**
1. **「 x64 Native Tools Command Prompt for VS 」を開く**
2. **環境変数を設定** (設定例です。環境依存です。)
   ```sh
   "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat"
   ```
3. **コンパイル**
   ```sh
   cl main.c
   main.exe
   ```

## **実行結果**
```sh
所要時間: 0.000123456 秒。
```
(*値はシステム性能に依存して変動します。実行するごとに状況に応じて変わることもあります。*)

## **用途**
- **簡単なコードブロックのパフォーマンス測定**
- **短いループの実行時間を測定**
- **異なるアルゴリズムのベンチマーク**

このライブラリは **高精度** かつ **低オーバーヘッド** なので、パフォーマンスクリティカルなアプリケーションにも最適なのではないでしょうか。