Help us understand the problem. What is going on with this article?

文字列を数値に変換する関数の速度比較 (C++)

More than 1 year has passed since last update.

はじめに

最近競技プログラミングを始めたこともあってか、string型の数字をint型に変換する機会がそこそこありました。
これまでは何となくstoi関数を使っていたのですが、似た処理とはどの程度の差があるのだろうか、と思い比較をしました。

比較対象

Cからatoi関数、sscanf関数、
C++からstoi関数、istringstream
の4つを比較します。

内容と環境

Try it Online上で実行しました。
ランダムに生成された100万個のstringをint型に変換し、経過した時間を計測します。
実行したコードは最下部に記載します。

実行結果

処理内容 処理時間 [ms]
atoi 41
sscanf 192
stoi 69
istringstream 544

まとめ・おわりに

単純に数値へと変換するならば、atoi関数が最も早かったです。
その他の処理も時間はともかく順位はイメージしていた結果を得ることができました。

計測結果だけの掲載になりましたが、ご覧いただきありがとうございます。

実行したコード

test.cpp
#include <iostream>
#include <random>
#include <chrono>
#include <string>
#include <sstream>

using namespace std;

constexpr int TRIAL = 1000000;
string strNums[TRIAL];

//c_strとatoiの組み合わせ
void try_atoi() {
  int num;
  for (int i = 0; i < TRIAL; i++) {
    num = atoi(strNums[i].c_str());
  }
}

//c_strとsscanfの組み合わせ
void try_sscanf() {
  int num;
  for (int i = 0; i < TRIAL; i++) {
    sscanf(strNums[i].c_str(), "%d", &num);
  }
}

void try_stoi() {
  int num;
  for (int i = 0; i < TRIAL; i++) {
    num = stoi(strNums[i]);
  }
}

void try_istringstream() {
  int num;
  for (int i = 0; i < TRIAL; i++) {
    std::istringstream(strNums[i]) >> num;
  }
}

//関数実行にかかった時間を返却
long long stopwatch(void(*func)()) {
  std::chrono::system_clock::time_point start, end;
  start = std::chrono::system_clock::now();
  func(); // 処理
  end = std::chrono::system_clock::now();
  return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

int main(void) {
  std::mt19937 mt((std::random_device())());
  mt.seed(1);
  std::uniform_int_distribution<> randInt(0, 2147483647);
  for (int i = 0; i < TRIAL; i++) {
    int tmp = randInt(mt);
    strNums[i] = to_string(tmp);
  }

  cout << "function :\ttime [ms]" << "\n";
  cout << "----------------------------" << "\n";
  cout << "atoi :\t\t" << stopwatch(&try_atoi) << "\n";
  cout << "sscanf :\t" << stopwatch(&try_sscanf) << "\n";
  cout << "stoi :\t\t" << stopwatch(&try_stoi) << "\n";
  cout << "istringstream:\t" << stopwatch(&try_istringstream) << "\n";


  return 0;
}
Hilary02
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away