速度比較。文字列の組み立て - AWK
文字列を組み立てる方法 ▲
o 単純に文字列を並べた時、2つの方法の実行速度を調べてみました。+ そのまま並べる方法
+ sprintfを使う方法
結果:
o どちらも、10万回で4秒程度でした。
o 但し、Gawk on Windows (3.1.7)上で sprintfを使うと、10万回で40秒前後まで遅くなりました。
+ mawk MBCS (32bit版) (1.3.3) の場合は、逆に、sprintfの方が数%程度速くなりました。
o どちらも、ウィルスチェックソフトなど、色々起動している中で測定しました。ですから、数字は特定環境下での目安です。
**** 実行方法
o 確認したAWKプログラムは
+ Gawk on Windows (3.1.7)
+ mawk MBCS (32bit版) (1.3.3)
o 確認したOSは、Windows XP
o 実行コマンドは
----------------
gawk.exe -f awkファイル名 > out_a_gawk.txt
mawk32.exe -f awkファイル名 > out_a_mawk.txt
----------------
o gettime.cpp -- systimeよりも高精度で測定する為の補助プログラム gettime.exeのソースコード
----------------
#include <windows.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
fprintf(stdout, "%u\n", GetTickCount());
return 0;
}
----------------
+ このプログラムはミリ秒を返しますが、実際の精度は 10ミリ秒(= 0.01秒)程度か、それ以下です。これに、パイプ実行分の誤差が加わります。
+ 0.1秒程度の精度があれば十分ですので、Windows APIの中から動作が軽いものを選びました。
+ 今回は文字列渡しですが、system関数経由の整数渡しにすると、もっと動作が速くなるかもしれません。
**** test1 = sprintf から先に実行した場合
o gettime は時間を取得するプログラムです。
+ 実行時の負荷が少ない、GetTickCount関数を使用して います。実行環境での精度は30ミリ秒程度です。
o 実行したAWKプログラム
----------------
function f_out(v_title_str, v_start, v_end, v_time) {
v_time = 0 + v_end - v_start;
print v_title_str " : " v_time " (msec)";
}
function f_test1(v_title) {
v_timer_cmd | getline v_start; close(v_timer_cmd);
for (i = 0; i < 1000000; ++i) {
v = sprintf("テストは%sと%sと%sと%sと%dです。", v1, v2, v3, v4, v5);
v = sprintf("数字は%dです。", v0);
}
v_timer_cmd | getline v_end; close(v_timer_cmd);
f_out(v_title, v_start, v_end);
}
function f_test2(v_title) {
v_timer_cmd | getline v_start; close(v_timer_cmd);
for (i = 0; i < 1000000; ++i) {
v = "テストは" v1 "と" v2 "と" v3 "と" v4 "と" v5 "です。";
v = "数字は" v0 "です。";
}
v_timer_cmd | getline v_end; close(v_timer_cmd);
f_out(v_title, v_start, v_end);
}
BEGIN {
v1 = "abcdefg";
v2 = "hijklmn";
v3 = "opqrstu";
v4 = "vwxyz";
v5 = 1234567890;
v0 = 0;
v_timer_cmd = "gettime";
f_test1("# 1. sprintfを使った場合。1回目");
f_test2("# 2. 変数を並べた場合。1回目");
f_test1("# 3. sprintfを使った場合。2回目");
f_test2("# 4. 変数を並べた場合。2回目");
f_test1("# 5. sprintfを使った場合。3回目");
f_test2("# 6. 変数を並べた場合。3回目");
exit;
}
----------------
o Gawk on Windows (3.1.7)
# 1. sprintfを使った場合。1回目 : 39266 (msec)
# 2. 変数を並べた場合。1回目 : 4125 (msec)
# 3. sprintfを使った場合。2回目 : 39296 (msec)
# 4. 変数を並べた場合。2回目 : 4265 (msec)
# 5. sprintfを使った場合。3回目 : 41844 (msec)
# 6. 変数を並べた場合。3回目 : 4312 (msec)
o mawk MBCS (32bit版) (1.3.3)
# 1. sprintfを使った場合。1回目 : 4266 (msec)
# 2. 変数を並べた場合。1回目 : 4312 (msec)
# 3. sprintfを使った場合。2回目 : 4235 (msec)
# 4. 変数を並べた場合。2回目 : 4375 (msec)
# 5. sprintfを使った場合。3回目 : 4187 (msec)
# 6. 変数を並べた場合。3回目 : 4375 (msec)
**** test2 = 変数を並べる書き方から先に実行した場合
o 実行したAWKプログラム
----------------
function f_out(v_title_str, v_start, v_end, v_time) {
v_time = 0 + v_end - v_start;
print v_title_str " : " v_time " (msec)";
}
function f_test1(v_title) {
v_timer_cmd | getline v_start; close(v_timer_cmd);
for (i = 0; i < 1000000; ++i) {
v = sprintf("テストは%sと%sと%sと%sと%dです。", v1, v2, v3, v4, v5);
v = sprintf("数字は%dです。", v0);
}
v_timer_cmd | getline v_end; close(v_timer_cmd);
f_out(v_title, v_start, v_end);
}
function f_test2(v_title) {
v_timer_cmd | getline v_start; close(v_timer_cmd);
for (i = 0; i < 1000000; ++i) {
v = "テストは" v1 "と" v2 "と" v3 "と" v4 "と" v5 "です。";
v = "数字は" v0 "です。";
}
v_timer_cmd | getline v_end; close(v_timer_cmd);
f_out(v_title, v_start, v_end);
}
BEGIN {
v1 = "abcdefg";
v2 = "hijklmn";
v3 = "opqrstu";
v4 = "vwxyz";
v5 = 1234567890;
v0 = 0;
v_timer_cmd = "gettime";
f_test2("# 1. 変数を並べた場合。1回目");
f_test1("# 2. sprintfを使った場合。1回目");
f_test2("# 3. 変数を並べた場合。2回目");
f_test1("# 4. sprintfを使った場合。2回目");
f_test2("# 5. 変数を並べた場合。3回目");
f_test1("# 6. sprintfを使った場合。3回目");
exit;
}
----------------
o Gawk on Windows (3.1.7)
# 1. 変数を並べた場合。1回目 : 4375 (msec)
# 2. sprintfを使った場合。1回目 : 39922 (msec)
# 3. 変数を並べた場合。2回目 : 4062 (msec)
# 4. sprintfを使った場合。2回目 : 39719 (msec)
# 5. 変数を並べた場合。3回目 : 4188 (msec)
# 6. sprintfを使った場合。3回目 : 39562 (msec)
o mawk MBCS (32bit版) (1.3.3)
# 1. 変数を並べた場合。1回目 : 4422 (msec)
# 2. sprintfを使った場合。1回目 : 4187 (msec)
# 3. 変数を並べた場合。2回目 : 4422 (msec)
# 4. sprintfを使った場合。2回目 : 4188 (msec)
# 5. 変数を並べた場合。3回目 : 4437 (msec)
# 6. sprintfを使った場合。3回目 : 4187 (msec)
==
関連ページ:
文字列を組み立てる方法
▼AWKの文字列操作関数と関連機能(▼ABC順)
▼AWKプログラムを書く(▼ABC順)
▼AWK
▼制作メモ
> 文字列から文字を1つずつ取り出す
文字列中で使用出来る特殊文字
> プログラムの基本パターン
ローカル変数を使う
(2010年9月11日追加。mawk32に対する詳細評価)
(2010年8月17日追加。補助プログラム gettimeのソースコード)