はじめに
最近競技プログラミングを始めたこともあってか、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;
}