C++/Win32API/ファイル入出力のセオリー
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
''[[FrontPage]]''
* ファイル入出力のセオリー [#b84c5cc4]
プログラム言語でファイルを扱うのにはいくつかセオリーがあ...
なにせハードディスクへのアクセスはメモリに比べるとかなり...
~
まず第一に、極力ハードディスクへのアクセス回数を減らすべ...
つまり実行速度を考慮した場合、ファイルへの出力はデータを...
まとめて一度に行うのが望ましく、読込む場合も、いったんメ...
展開してから、検索するなり編集するなりといった方が望まし...
~
当然ですが、ファイルオープン・クローズ回数は、できる限り...
とはいえ、アプリケーションを起動した時点でファイルをオー...
終了させるまでそのまま開きっぱなし、というのも非常にセン...
排他制御が効きっぱなしになりますし、予期せぬ事態が起こら...
~
さて今回は例として、ファイル出力の方法について8パターンの...
これは私の製作するwindowsアプリケーションの評価のために行...
動的メモリ確保にnew()のみを使用していたり、読者様の指向と...
あるとは思いますが、ファイル入出力方法で外せないポイント...
本質とはあまり関係のない問題と考えますので、ご了承くださ...
~
** 結果から得られる情報 [#q57af331]
int型データ10万個程度の試行では・・・・~
+ 一般的に、ファイルへの書込みはまとめて実行した方が速度...
+ ファイルオープン・クローズだけならWin32APIとCライブラリ...
WriteFile()に比べ、Cライブラリのfwrite()は実行速度的に優...
windowsアプリでもCライブラリ関数を用いることは、移植性も...
+ 費用対効果を考えると、fwrite()関数を用いる場合、自ら大...
ファイル出力をまとめる必要性は少ないと言える。(特記事項ii...
+ 動的確保でも静的配列でも、一度だけならほとんど実行時間...
動的メモリ確保の方が好ましいと考えられる。(特記事項iii参...
*** 特記事項 [#l9d923d1]
++ fopen()を使ってファイル操作を行う場合、windows上ではフ...
++ fwrite()関数はstdio.h内で定義される大きさの内部バッフ...
++ 環境にもよるが、万単位で静的な配列を宣言するのは、連続...
*** 出力結果 [#r185e1d1]
100000 times open, write and close, using win32API.
it takes 277321 msec.
100000 times WriteFile().
it takes 299 msec.
one time WriteFile(), using new().
it takes 6 msec.
one time WriteFile(), using array.
it takes 5 msec.
100000 times open, write and close, using C library.
it takes 277634 msec.
100000 times fwrite().
it takes 13 msec.
one time fwrite(), using new().
it takes 6 msec.
one time fwrite(), using array.
it takes 6 msec.
*** fileTest.cpp [#v78115db]
#include <stdio.h> ...
#include <time.h> ...
#include <windows.h> ...
...
#define TEST_NUM 100000 ...
...
/* File Test *******************************************...
int main( void ) ...
{ ...
clock_t start, end; ...
HANDLE OUFO_API; ...
DWORD writtenSize; ...
FILE *OUFO_C; ...
...
int data = 0x7234ABCD; ...
int cnt; ...
...
int buf_arr[TEST_NUM]; ...
int *buf_new; ...
...
LARGE_INTEGER li; ...
li.LowPart = 0; ...
li.HighPart = 0; ...
...
for( ; ; ) ...
{ ...
/* API Open Write Close Each Time **********************...
start = clock(); ...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
OUFO_API = CreateFile( ".\\a.txt", ...
GENERIC_WRITE, ...
FILE_SHARE_READ, ...
NULL, ...
OPEN_ALWAYS, ...
FILE_ATTRIBUTE_NORMAL...
NULL ); ...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
break; ...
} ...
...
SetFilePointerEx( OUFO_API, li, NULL, FILE_E...
WriteFile( OUFO_API, &data, sizeof(int), &wr...
...
data--; ...
...
CloseHandle( OUFO_API ); ...
} ...
end = clock(); ...
printf( "%d times open, write and close, using w...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Open Write Close Each Time **********************...
/* API Write Each Time *********************************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_API = CreateFile( ".\\b.txt", GENERIC_WRITE...
NULL, OPEN_ALWAYS, FILE_A...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
WriteFile( OUFO_API, &data, sizeof(int), &wr...
data--; ...
} ...
...
CloseHandle( OUFO_API ); ...
...
end = clock(); ...
printf( "%d times WriteFile().\n", TEST_NUM ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Write Each Time *********************************...
/* API Write in One using Dynamically Allocated Array **...
data = 0x7234ABCD; ...
start = clock(); ...
...
buf_new = new int[TEST_NUM]; ...
...
OUFO_API = CreateFile( ".\\c.txt", GENERIC_WRITE...
NULL, OPEN_ALWAYS, FILE_A...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_new[cnt] = data--; ...
} ...
...
WriteFile( OUFO_API, buf_new, sizeof(int) * TEST...
...
delete [] buf_new; ...
...
CloseHandle( OUFO_API ); ...
...
end = clock(); ...
printf( "one time WriteFile(), using new().\n" )...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Write in One using Dynamically Allocated Array **...
/* API Write in One using Static Array *****************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_API = CreateFile( ".\\d.txt", GENERIC_WRITE...
NULL, OPEN_ALWAYS, FILE_A...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_arr[cnt] = data--; ...
} ...
...
WriteFile( OUFO_API, buf_arr, sizeof(buf_arr), &...
...
CloseHandle( OUFO_API ); ...
...
end = clock(); ...
printf( "one time WriteFile(), using array.\n" )...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Write in One using Static Array *****************...
/* C Open Write Close Each Time ************************...
data = 0x7234ABCD; ...
start = clock(); ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
OUFO_C = fopen( "e.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
break; ...
} ...
...
fwrite( &data, sizeof(int), 1, OUFO_C ); ...
data--; ...
...
fclose( OUFO_C ); ...
} ...
...
end = clock(); ...
printf( "%d times open, write and close, using C...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Open Write Close Each Time ************************...
/* C Write Each Time ***********************************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_C = fopen( "f.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
fwrite( &data, sizeof(int), 1, OUFO_C ); ...
data--; ...
} ...
fclose( OUFO_C ); ...
end = clock(); ...
printf( "%d times fwrite().\n", TEST_NUM ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Write Each Time ***********************************...
/* C Write in One using Dynamically Allocated Array ****...
data = 0x7234ABCD; ...
start = clock(); ...
...
buf_new = new int[TEST_NUM]; ...
...
OUFO_C = fopen( "g.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_new[cnt] = data--; ...
} ...
...
fwrite( buf_new, sizeof(int), TEST_NUM, OUFO_C )...
...
fclose( OUFO_C ); ...
...
delete [] buf_new; ...
...
end = clock(); ...
printf( "one time fwrite(), using new().\n" ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Write in One using Dynamically Allocated Array ****...
/* C Write in One using Static Array *******************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_C = fopen( "h.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_arr[cnt] = data--; ...
} ...
...
fwrite( buf_arr, sizeof(int), TEST_NUM, OUFO_C )...
...
fclose( OUFO_C ); ...
...
end = clock(); ...
printf( "one time fwrite(), using array.\n" ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Write in One using Static Array *******************...
break; ...
} ...
...
return( 0 ); ...
} ...
//*File Test *******************************************...
*** 修正履歴 [#ib703c84]
~
*** 課題 [#bd5dac0b]
+ 試行回数10万回というのは大きすぎて危険か?~
→ C99の場合、65535バイトまでしか保証されないらしい。
+ fwrite()関数がなぜWriteFile()より速いのか、何か見落とし...
→ CreateFile()のオプション指定の仕方など
暇があればさらに調べてみます。~
*** 備考 [#u2a5eb6a]
テスト中に他の作業するとテスト結果に影響でるよ!~
*** 参考リンク [#b828049a]
[[fwriteのバッファサイズ変更:http://www.cc.u-tokyo.ac.jp/...
終了行:
''[[FrontPage]]''
* ファイル入出力のセオリー [#b84c5cc4]
プログラム言語でファイルを扱うのにはいくつかセオリーがあ...
なにせハードディスクへのアクセスはメモリに比べるとかなり...
~
まず第一に、極力ハードディスクへのアクセス回数を減らすべ...
つまり実行速度を考慮した場合、ファイルへの出力はデータを...
まとめて一度に行うのが望ましく、読込む場合も、いったんメ...
展開してから、検索するなり編集するなりといった方が望まし...
~
当然ですが、ファイルオープン・クローズ回数は、できる限り...
とはいえ、アプリケーションを起動した時点でファイルをオー...
終了させるまでそのまま開きっぱなし、というのも非常にセン...
排他制御が効きっぱなしになりますし、予期せぬ事態が起こら...
~
さて今回は例として、ファイル出力の方法について8パターンの...
これは私の製作するwindowsアプリケーションの評価のために行...
動的メモリ確保にnew()のみを使用していたり、読者様の指向と...
あるとは思いますが、ファイル入出力方法で外せないポイント...
本質とはあまり関係のない問題と考えますので、ご了承くださ...
~
** 結果から得られる情報 [#q57af331]
int型データ10万個程度の試行では・・・・~
+ 一般的に、ファイルへの書込みはまとめて実行した方が速度...
+ ファイルオープン・クローズだけならWin32APIとCライブラリ...
WriteFile()に比べ、Cライブラリのfwrite()は実行速度的に優...
windowsアプリでもCライブラリ関数を用いることは、移植性も...
+ 費用対効果を考えると、fwrite()関数を用いる場合、自ら大...
ファイル出力をまとめる必要性は少ないと言える。(特記事項ii...
+ 動的確保でも静的配列でも、一度だけならほとんど実行時間...
動的メモリ確保の方が好ましいと考えられる。(特記事項iii参...
*** 特記事項 [#l9d923d1]
++ fopen()を使ってファイル操作を行う場合、windows上ではフ...
++ fwrite()関数はstdio.h内で定義される大きさの内部バッフ...
++ 環境にもよるが、万単位で静的な配列を宣言するのは、連続...
*** 出力結果 [#r185e1d1]
100000 times open, write and close, using win32API.
it takes 277321 msec.
100000 times WriteFile().
it takes 299 msec.
one time WriteFile(), using new().
it takes 6 msec.
one time WriteFile(), using array.
it takes 5 msec.
100000 times open, write and close, using C library.
it takes 277634 msec.
100000 times fwrite().
it takes 13 msec.
one time fwrite(), using new().
it takes 6 msec.
one time fwrite(), using array.
it takes 6 msec.
*** fileTest.cpp [#v78115db]
#include <stdio.h> ...
#include <time.h> ...
#include <windows.h> ...
...
#define TEST_NUM 100000 ...
...
/* File Test *******************************************...
int main( void ) ...
{ ...
clock_t start, end; ...
HANDLE OUFO_API; ...
DWORD writtenSize; ...
FILE *OUFO_C; ...
...
int data = 0x7234ABCD; ...
int cnt; ...
...
int buf_arr[TEST_NUM]; ...
int *buf_new; ...
...
LARGE_INTEGER li; ...
li.LowPart = 0; ...
li.HighPart = 0; ...
...
for( ; ; ) ...
{ ...
/* API Open Write Close Each Time **********************...
start = clock(); ...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
OUFO_API = CreateFile( ".\\a.txt", ...
GENERIC_WRITE, ...
FILE_SHARE_READ, ...
NULL, ...
OPEN_ALWAYS, ...
FILE_ATTRIBUTE_NORMAL...
NULL ); ...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
break; ...
} ...
...
SetFilePointerEx( OUFO_API, li, NULL, FILE_E...
WriteFile( OUFO_API, &data, sizeof(int), &wr...
...
data--; ...
...
CloseHandle( OUFO_API ); ...
} ...
end = clock(); ...
printf( "%d times open, write and close, using w...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Open Write Close Each Time **********************...
/* API Write Each Time *********************************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_API = CreateFile( ".\\b.txt", GENERIC_WRITE...
NULL, OPEN_ALWAYS, FILE_A...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
WriteFile( OUFO_API, &data, sizeof(int), &wr...
data--; ...
} ...
...
CloseHandle( OUFO_API ); ...
...
end = clock(); ...
printf( "%d times WriteFile().\n", TEST_NUM ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Write Each Time *********************************...
/* API Write in One using Dynamically Allocated Array **...
data = 0x7234ABCD; ...
start = clock(); ...
...
buf_new = new int[TEST_NUM]; ...
...
OUFO_API = CreateFile( ".\\c.txt", GENERIC_WRITE...
NULL, OPEN_ALWAYS, FILE_A...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_new[cnt] = data--; ...
} ...
...
WriteFile( OUFO_API, buf_new, sizeof(int) * TEST...
...
delete [] buf_new; ...
...
CloseHandle( OUFO_API ); ...
...
end = clock(); ...
printf( "one time WriteFile(), using new().\n" )...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Write in One using Dynamically Allocated Array **...
/* API Write in One using Static Array *****************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_API = CreateFile( ".\\d.txt", GENERIC_WRITE...
NULL, OPEN_ALWAYS, FILE_A...
if( INVALID_HANDLE_VALUE == OUFO_API ) ...
{ ...
printf( "ERR: CreateFile()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_arr[cnt] = data--; ...
} ...
...
WriteFile( OUFO_API, buf_arr, sizeof(buf_arr), &...
...
CloseHandle( OUFO_API ); ...
...
end = clock(); ...
printf( "one time WriteFile(), using array.\n" )...
printf( "it takes %d msec.\n\n", end - start ); ...
//*API Write in One using Static Array *****************...
/* C Open Write Close Each Time ************************...
data = 0x7234ABCD; ...
start = clock(); ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
OUFO_C = fopen( "e.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
break; ...
} ...
...
fwrite( &data, sizeof(int), 1, OUFO_C ); ...
data--; ...
...
fclose( OUFO_C ); ...
} ...
...
end = clock(); ...
printf( "%d times open, write and close, using C...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Open Write Close Each Time ************************...
/* C Write Each Time ***********************************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_C = fopen( "f.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
fwrite( &data, sizeof(int), 1, OUFO_C ); ...
data--; ...
} ...
fclose( OUFO_C ); ...
end = clock(); ...
printf( "%d times fwrite().\n", TEST_NUM ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Write Each Time ***********************************...
/* C Write in One using Dynamically Allocated Array ****...
data = 0x7234ABCD; ...
start = clock(); ...
...
buf_new = new int[TEST_NUM]; ...
...
OUFO_C = fopen( "g.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_new[cnt] = data--; ...
} ...
...
fwrite( buf_new, sizeof(int), TEST_NUM, OUFO_C )...
...
fclose( OUFO_C ); ...
...
delete [] buf_new; ...
...
end = clock(); ...
printf( "one time fwrite(), using new().\n" ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Write in One using Dynamically Allocated Array ****...
/* C Write in One using Static Array *******************...
data = 0x7234ABCD; ...
start = clock(); ...
...
OUFO_C = fopen( "h.txt", "ab" ); ...
if( NULL == OUFO_C ) ...
{ ...
printf( "ERR: fopen()\n" ); ...
} ...
...
for( cnt = 0; TEST_NUM > cnt; cnt++ ) ...
{ ...
buf_arr[cnt] = data--; ...
} ...
...
fwrite( buf_arr, sizeof(int), TEST_NUM, OUFO_C )...
...
fclose( OUFO_C ); ...
...
end = clock(); ...
printf( "one time fwrite(), using array.\n" ); ...
printf( "it takes %d msec.\n\n", end - start ); ...
//*C Write in One using Static Array *******************...
break; ...
} ...
...
return( 0 ); ...
} ...
//*File Test *******************************************...
*** 修正履歴 [#ib703c84]
~
*** 課題 [#bd5dac0b]
+ 試行回数10万回というのは大きすぎて危険か?~
→ C99の場合、65535バイトまでしか保証されないらしい。
+ fwrite()関数がなぜWriteFile()より速いのか、何か見落とし...
→ CreateFile()のオプション指定の仕方など
暇があればさらに調べてみます。~
*** 備考 [#u2a5eb6a]
テスト中に他の作業するとテスト結果に影響でるよ!~
*** 参考リンク [#b828049a]
[[fwriteのバッファサイズ変更:http://www.cc.u-tokyo.ac.jp/...
ページ名: