いくつかの実験:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
void generateFiles(int n) {
char fileName[32];
char fileStr[1032];
for (int i=0;i<n;i++) {
sprintf( fileName, "c:\\t\\%i.txt", i );
FILE * f = fopen( fileName, "w" );
for (int j=0;j<256;j++) {
int lineLen = rand() % 1024;
memset(fileStr, 'X', lineLen );
fileStr[lineLen] = 0x0D;
fileStr[lineLen+1] = 0x0A;
fileStr[lineLen+2] = 0x00;
fwrite( fileStr, 1, lineLen+2, f );
}
fclose(f);
}
}
void readFiles(int n) {
char fileName[32];
for (int i=0;i<n;i++) {
sprintf( fileName, "c:\\t\\%i.txt", i );
FILE * f = fopen( fileName, "r" );
fseek(f, 0L, SEEK_END);
int size = ftell(f);
fseek(f, 0L, SEEK_SET);
char * data = (char*)malloc(size);
fread(data, size, 1, f);
free(data);
fclose(f);
}
}
DWORD WINAPI readInThread( LPVOID lpParam )
{
int * number = (int *)lpParam;
char fileName[32];
sprintf( fileName, "c:\\t\\%i.txt", *number );
FILE * f = fopen( fileName, "r" );
fseek(f, 0L, SEEK_END);
int size = ftell(f);
fseek(f, 0L, SEEK_SET);
char * data = (char*)malloc(size);
fread(data, size, 1, f);
free(data);
fclose(f);
return 0;
}
int main(int argc, char ** argv) {
long t1 = GetTickCount();
generateFiles(256);
printf("Write: %li ms\n", GetTickCount() - t1 );
t1 = GetTickCount();
readFiles(256);
printf("Read: %li ms\n", GetTickCount() - t1 );
t1 = GetTickCount();
const int MAX_THREADS = 256;
int pDataArray[MAX_THREADS];
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
for( int i=0; i<MAX_THREADS; i++ )
{
pDataArray[i] = (int) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(int));
pDataArray[i] = i;
hThreadArray[i] = CreateThread(
NULL,
0,
readInThread,
&pDataArray[i],
0,
&dwThreadIdArray[i]);
}
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
printf("Read (threaded): %li ms\n", GetTickCount() - t1 );
}
最初の関数は、テストデータセットを作成するための醜いものです(もっとうまくできることはわかっていますが、正直なところ時間がありません)
1 回目の実験 - シーケンシャル読み取り 2 回目の実験 - すべてを並行して読み取る
結果:
256 ファイル:
Write: 250 ms
Read: 140 ms
Read (threaded): 78 ms
1024 ファイル:
Write: 1250 ms
Read: 547 ms
Read (threaded): 843 ms
2 回目の試行は、長期的には「ダム」スレッドの作成が事態をさらに悪化させることを明確に示していると思います。もちろん、事前に割り当てられたワーカー、いくつかのスレッド プールなどの点で改善が必要ですが、ディスクから 100 ~ 200k を読み取るような高速な操作では、この機能をスレッドに移動するメリットはないと思います。もっと「賢い」ソリューションを書く時間はありませんが、ミューテックスなどのシステムコールを追加する必要があるため、はるかに高速になるとは思えません...
極端に行くと、メモリプールなどを事前に割り当てることを考えることができます..しかし、前に述べたように、コードが間違って投稿されました..それは数ミリ秒の問題ですが、確かに数秒ではありません
800 ファイル (1 行あたり 20 文字、256 行)
Write: 250 ms
Read: 63 ms
Read (threaded): 500 ms
結論:
答えは:
読み取りコードが間違っています。ファイルの読み取りが非常に遅いため、速度が大幅に向上し、タスクを並行して実行します。上記のコードでは、読み取りは実際にはスレッドを生成するための費用よりも高速です