각 파일의 첫 번째 항목 인 키를 기준으로 큰 파일 (큰 따옴표로 묶은 각 용어)을 많은 작은 파일로 분할하려고합니다. 일반적으로 동일한 키를 사용하는 하나 이상의 레코드입니다.하나의 파일을 여러 개의 작은 파일로 분할하기위한 최적화
이 큰 파일의 범위는 1GB에서 2GB까지이며, 생성되는 파일의 수는 키의 이름을 따서 명명 된 하위 폴더에 각각 10,000-30,000입니다.
C#에서는 각 행에서 StreamReader.ReadLine()을 수행하고 결과가 다른 키 (이전 키의 마지막 데이터를 알리는 신호)에 도달 할 때까지 연결 한 다음 파일을 쓰는 함수를 호출합니다 비 동시성으로. Windows에서 이러한 파일을 정렬하여 일련의 키를 만들도록 요청하고 있습니다. 따라서 한 번 파일을 열어야 만합니다. 그러나 작업을 완료하는 데 20 분 정도 걸립니다. 이 속도를 높이는 방법이 있습니까? 애프터 (
sfd = new SaveFileDataDelegate(this.SaveFileData);
private void CSVParse(string filename, string unzippedFilePath, string feedname)
{
StreamReader filestream = null;
FileStream readerStream = null;
try
{
readerStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None, 120000, FileOptions.SequentialScan);
filestream = new StreamReader(readerStream, Encoding.UTF8, false, 120000);
string tempstring = "";
string buffer = "";
string lastlotkey = "";
IAsyncResult result = null;
activityLog.Log("Parsing File: " + filename);
while (((tempstring = filestream.ReadLine()) != null) || buffer != "")
{
if (tempstring == null)
{
tempstring = "";
}
string lotkey = tempstring.Replace("\"","").Split(',').First();
if (lotkey == tempstring && tempstring != "")
{
break;
}
if (lotkey == "DealerID")
{
continue;
}
if (lastlotkey == "")
{
lastlotkey = lotkey;
}
if ((lotkey != lastlotkey && buffer.Length > 0))
{
result = sfd.BeginInvoke(outputDirectory + @"\" + feedname + @"\" + lastlotkey + @"\" + (filename.Split('\\').Last()).Split('.').First() + ".txt", buffer, outputDirectory + @"\" + feedname + @"\" + lastlotkey,null,null);
lastlotkey = lotkey;
buffer = "";
if (tempstring == "")
{
continue;
}
}
if (buffer.Length > 0)
{
buffer = buffer + "\r\n";
}
buffer = buffer + tempstring;
}
filestream.Close();
readerStream.Close();
if (result != null)
{
result.AsyncWaitHandle.WaitOne(-1);
}
return;
}
catch (Exception e)
{
activityLog.Log("Error Occurred: " + e.ToString());
if (filestream != null)
{
filestream.Close();
}
hadError = true;
return;
}
}
private void SaveFileData(string file, string buffer, string directory)
{
// create file from last lot key with data from parsing, write, close, update lastlotkey
Directory.CreateDirectory(directory);
FileStream fs = null;
StreamWriter temp = null;
try
{
if (!File.Exists(file))
{
fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 120000);
}
else
{
fs = new FileStream(file, FileMode.Truncate, FileAccess.Write, FileShare.None, 120000);
}
temp = new StreamWriter(fs, Encoding.UTF8, 120000);
temp.AutoFlush = false;
temp.WriteLine(headerLine);
temp.Write(buffer);
temp.Flush();
temp.Close();
fs.Close();
}
catch (Exception e)
{
activityLog.Log("Error Occurred: " + e.ToString());
if (fs != null)
{
fs.Close();
}
if (temp != null)
{
temp.Close();
}
hadError = true;
return;
}
}
편집
나는 스택 오버플로와 인터넷의 깊은 창자 크롤링 및 라인으로 라인을 프로파일 링 후에 나는 문자열 연결 실제로 파싱 루틴의 무거운 것을 발견 파일 복사 및 윈도우 정렬), Stringbuilder로 바꾸면 총 처리 시간이 20 분 (복사 + 정렬 + 구문 분석)에서 5 분의 복사 + 정렬 및 2 분의 구문 분석, 총 7 분으로 대폭 늘어났습니다. 속도 향상 130 %
StringBuilder가 다시 나타납니다. 부적절하게 String으로 작성된 프로그램을 디버깅하는 데 낭비되는 시간 낭비가 String internation에 의해 세계에 저장된 총 메모리를 초과했는지 의문입니다. –