测量 win api和c++标准库的字符集转换性能 (win的API性能好一倍多)

#include <benchmark/benchmark.h>
#include <iostream>
#include <codecvt>
#include <windows.h>
#pragma comment(lib,"Shlwapi.lib")

wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8) {
  wchar_t *str_w = NULL;

  if (str_utf8) {
    int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str_utf8,
                                        -1, NULL, 0);
    if (str_w_len > 0) {
      str_w = (wchar_t*)malloc(str_w_len * sizeof(wchar_t));
      if (str_w) {
        if (MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w, str_w_len) ==
            0) {
          free(str_w);
          return NULL;
        }
      }
    }
  }

  return str_w;
}

char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w) {
  char *str_utf8 = NULL;

  if (str_w) {
    int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL, 0, NULL, NULL);
    if (bytes > 0) {
      str_utf8 = (char*)malloc(bytes);
      if (str_utf8) {
        if (WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes, NULL,
                                NULL) == 0) {
          free(str_utf8);
          return NULL;
        }
      }
    }
  }

  return str_utf8;
}

// unicode转utf-8
std::string to_utf8(const std::wstring &wide_string) {
  static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;

  return utf8_conv.to_bytes(wide_string);
}

// utf-8转unicode
std::wstring to_utf16(const std::string &u8string) {
  static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>
      utf16_conv;

  return utf16_conv.from_bytes(u8string);
}

static std::wstring ws1(L"12321321321321dsadsadsaczxczcxc十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达");
static std::wstring ws2(L"12321321321321dsadsadsaczxczcxc十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达十大打撒打撒萨达");


void std_code_cvt() {
  auto t = to_utf8(ws1);
  auto t2 = to_utf16(t);
  return;
}

void win_native_code_cvt() {
  auto t = Curl_convert_wchar_to_UTF8(ws1.c_str());
  auto t2 = Curl_convert_UTF8_to_wchar(t);
  free(t);
  free(t2);
  return;
}

static void BM_SomeFunction(benchmark::State& state) {
    // Perform setup here
      static int count = 0;
    for (auto _ : state) {
      for (int i = 0; i < 100000; i++) {
        std_code_cvt();
      }
    }
}
static void BM_SomeFunction2(benchmark::State &state) {
  // Perform setup here
  static int count = 0;
  for (auto _ : state) {
    for (int i = 0; i < 100000; i++) {
      win_native_code_cvt();
    }
  }
}
// Register the function as a benchmark
BENCHMARK(BM_SomeFunction)->Unit(benchmark::kSecond);
BENCHMARK(BM_SomeFunction2)->Unit(benchmark::kSecond);
// Run the benchmark
BENCHMARK_MAIN();