出力関数による速度の差について
出力関数の速度について調べてみました。調査方法は、time
コマンドを使って1000万行のテキストファイルを読み込んで、標準出力とファイル出力します。何度か実行してみて、早かった順のタイムを3つ提示しました。
環境:Macbook 2020(i7 1.2GHz, RAM 16GB)、gcc 11.2.0
入力関数は、putc()
、fputc()
の時はfgetc()
を、それ以外はfgets()
を使います。出力関数は、fputc()
、printf()
、puts()
、fputs()
を対象としています。なお、puts()
を使う時は、文字列の改行コードを削るのにstrlen()
、strtok()
も使うものとします。
結論
fgetc()
、fputc()
は非常に遅く、また速度にばらつきがあります。他の関数は全て同じくらいの速さです。とはいえ、1000万行もあるファイルでの話ですから、使い方によっては誤差の範囲かも知れません。
関数 | 出力先 | 速度1 | 速度2 | 速度3 |
---|---|---|---|---|
getc() |
標準出力 | 1m7.786s |
1m10.816s |
1m21.650s |
printf() |
標準出力 | 0m33.246s |
0m33.769s |
0m33.991s |
puts() + strtok() |
標準出力 | 0m32.217s |
0m32.603s |
0m32.825s |
puts() + strlen() |
標準出力 | 0m33.398s |
0m33.869s |
0m33.912s |
fputs() |
標準出力 | 0m32.044s |
0m32.628s |
0m32.730s |
fputc() |
ファイル出力 | 0m47.236s |
0m48.154s |
0m49.020s |
fprintf() |
ファイル出力 | 0m1.909s |
0m1.928s |
0m1.967s |
fputs() |
ファイル出力 | 0m1.903s |
0m1.932s |
0m1.954s |
基本となるコード
標準出力の場合、以下のコードのoutput()
を変更します。引数にファイルを指定すると標準出力されます。cat
コマンドのような振る舞いをします。なお、速度を調査することが目的なので、エラー処理は一切行っていません。
#include <stdio.h>
#include <string.h> // when using strtok() || strlen()
static void output(FILE *fp);
int main(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++) {
FILE *fp;
fp = fopen(argv[i], "r");
output(fp);
fclose(fp);
}
return 0;
}
ファイル出力は、以下のコードのoutputFile()
を変更します。実行ファイルの第1引数に出力ファイルを、第2引数以降に入力ファイルを指定します。
#include <stdio.h>
static void outputFile(FILE *fpo, FILE *fpi);
int main(int argc, char *argv[])
{
FILE *fpo;
int i;
fpo = fopen(argv[1], "a");
for (i = 2; i < argc; i++) {
FILE *fpi;
fpi = fopen(argv[i], "r");
outputFile(fpo, fpi);
fclose(fpi);
}
fclose(fpo);
return 0;
}
標準出力
putc()
static void output(FILE *fp)
{
int c;
while ((c = fgetc(fp)) != EOF) {
putc(c, stdout);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 1m7.786s |
1m10.816s |
1m21.650s |
user | 0m58.860s |
1m1.486s |
1m10.747s |
sys | 0m8.392s |
0m8.794s |
0m10.197s |
printf()
static void output(FILE *fp)
{
const int MaxLength = 256;
char buf[MaxLength];
while (fgets(buf,MaxLength,fp) != NULL) {
printf("%s", buf);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 0m33.246s |
0m33.769s |
0m33.991s |
user | 0m7.399s |
0m7.416s |
0m7.530s |
sys | 0m9.374s |
0m9.364s |
0m9.490s |
puts() + strtok()
static void output(FILE *fp)
{
const int MaxLength = 256;
char buf[MaxLength];
while (fgets(buf,MaxLength,fp) != NULL) {
strtok(buf, "\n");
puts(buf);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 0m32.217s |
0m32.603s |
0m32.825s |
user | 0m7.471s |
0m7.656s |
0m7.537s |
sys | 0m8.727s |
0m8.989s |
0m8.685s |
puts() + strlen()
static void output(FILE *fp)
{
const int MaxLength = 256;
char buf[MaxLength];
while (fgets(buf,MaxLength,fp) != NULL) {
buf[strlen(buf)-1] = '\0';
puts(buf);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 0m33.398s |
0m33.869s |
0m33.912s |
user | 0m6.163s |
0m6.228s |
0m6.216s |
sys | 0m9.053s |
0m9.116s |
0m9.180s |
fputs()
static void output(FILE *fp)
{
const int MaxLength = 256;
char buf[MaxLength];
while (fgets(buf,MaxLength,fp) != NULL) {
fputs(buf, stdout);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 0m32.044s |
0m32.628s |
0m32.730s |
user | 0m5.738s |
0m5.883s |
0m5.858s |
sys | 0m8.729s |
0m8.922s |
0m8.901s |
ファイル出力
fputc()
static void outputFile(FILE *fpo, FILE *fpi)
{
char c;
while ((c = fgetc(fpi)) != EOF) {
fputc(c, fpo);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 0m47.236s |
0m48.154s |
0m49.020s |
user | 0m45.435s |
0m46.581s |
0m47.170s |
sys | 0m1.035s |
0m1.073s |
0m1.084s |
fprintf()
static void outputFile(FILE *fpo, FILE *fpi)
{
const int MaxLength = 256;
char buf[MaxLength];
while (fgets(buf,MaxLength,fpi) != NULL) {
printf(fpo, "%s", buf);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 0m1.909s |
0m1.928s |
0m1.967s |
user | 0m0.932s |
0m0.948s |
0m0.954s |
sys | 0m0.839s |
0m0.845s |
0m0.841s |
fputs()
static void outputFile(FILE *fpo, FILE *fpi)
{
const int MaxLength = 256;
char buf[MaxLength];
while (fgets(buf,MaxLength,fpi) {
fputs(buf, fpo);
}
}
1st | 2nd | 3rd | |
---|---|---|---|
real | 0m1.903s |
0m1.932s |
0m1.954s |
user | 0m0.949s |
0m0.975s |
0m0.956s |
sys | 0m0.835s |
0m0.849s |
0m0.853s |