Tôi có một công cụ để so sánh 2 tệp csv và sau đó đưa từng ô vào một trong 6 nhóm. Về cơ bản, nó đọc trong các tập tin csv (sử dụng nhanh csv đọc, tín dụng: http://www.codeproject.com/KB/database/CsvReader.aspx) và sau đó tạo ra một từ điển liên quan đến mỗi tập tin dựa trên các phím được cung cấp bởi người sử dụng. Sau đó tôi lặp qua các từ điển thứ hai so sánh các giá trị và viết một tệp csv kết quả.C# Từ điển và Sử dụng Bộ nhớ Hiệu quả
Trong khi nó rất nhanh, việc sử dụng bộ nhớ rất kém hiệu quả. Tôi không thể so sánh hơn 150 MB tệp trên hộp của tôi với bộ nhớ vật lý 3 GB.
Đây là đoạn mã để đọc tệp mong muốn. Ở cuối đoạn này, việc sử dụng bộ nhớ là gần 500 MB từ trình quản lý tác vụ.
// Read Expected
long rowNumExp;
System.IO.StreamReader readerStreamExp = new System.IO.StreamReader(@expFile);
SortedDictionary<string, string[]> dictExp = new SortedDictionary<string, string[]>();
List<string[]> listDupExp = new List<string[]>();
using (CsvReader readerCSVExp = new CsvReader(readerStreamExp, hasHeaders, 4096))
{
readerCSVExp.SkipEmptyLines = false;
readerCSVExp.DefaultParseErrorAction = ParseErrorAction.ThrowException;
readerCSVExp.MissingFieldAction = MissingFieldAction.ParseError;
fieldCountExp = readerCSVExp.FieldCount;
string keyExp;
string[] rowExp = null;
while (readerCSVExp.ReadNextRecord())
{
if (hasHeaders == true)
{
rowNumExp = readerCSVExp.CurrentRecordIndex + 2;
}
else
{
rowNumExp = readerCSVExp.CurrentRecordIndex + 1;
}
try
{
rowExp = new string[fieldCount + 1];
}
catch (Exception exExpOutOfMemory)
{
MessageBox.Show(exExpOutOfMemory.Message);
Environment.Exit(1);
}
keyExp = readerCSVExp[keyColumns[0] - 1];
for (int i = 1; i < keyColumns.Length; i++)
{
keyExp = keyExp + "|" + readerCSVExp[i - 1];
}
try
{
readerCSVExp.CopyCurrentRecordTo(rowExp);
}
catch (Exception exExpCSVOutOfMemory)
{
MessageBox.Show(exExpCSVOutOfMemory.Message);
Environment.Exit(1);
}
try
{
rowExp[fieldCount] = rowNumExp.ToString();
}
catch (Exception exExpRowNumOutOfMemory)
{
MessageBox.Show(exExpRowNumOutOfMemory.Message);
Environment.Exit(1);
}
// Dedup Expected
if (!(dictExp.ContainsKey(keyExp)))
{
dictExp.Add(keyExp, rowExp);
}
else
{
listDupExp.Add(rowExp);
}
}
logFile.WriteLine("Done Reading Expected File at " + DateTime.Now);
Console.WriteLine("Done Reading Expected File at " + DateTime.Now + "\r\n");
logFile.WriteLine("Done Creating Expected Dictionary at " + DateTime.Now);
logFile.WriteLine("Done Identifying Expected Duplicates at " + DateTime.Now + "\r\n");
}
Tôi có thể làm gì để làm cho bộ nhớ hiệu quả hơn không? Bất cứ điều gì tôi có thể làm khác đi ở trên, để tiêu thụ ít mermory?
Mọi ý tưởng đều được chào đón.
Cảm ơn mọi người vì tất cả các phản hồi.
Tôi đã kết hợp các thay đổi như được đề xuất để lưu trữ chỉ mục của hàng thay vì chính hàng trong từ điển.
Đây là đoạn mã giống với triển khai mới.
// Read Expected
long rowNumExp;
SortedDictionary<string, long> dictExp = new SortedDictionary<string, long>();
System.Text.StringBuilder keyExp = new System.Text.StringBuilder();
while (readerCSVExp.ReadNextRecord())
{
if (hasHeaders == true)
{
rowNumExp = readerCSVExp.CurrentRecordIndex + 2;
}
else
{
rowNumExp = readerCSVExp.CurrentRecordIndex + 1;
}
for (int i = 0; i < keyColumns.Length - 1; i++)
{
keyExp.Append(readerCSVExp[keyColumns[i] - 1]);
keyExp.Append("|");
}
keyExp.Append(readerCSVExp[keyColumns[keyColumns.Length - 1] - 1]);
// Dedup Expected
if (!(dictExp.ContainsKey(keyExp.ToString())))
{
dictExp.Add(keyExp.ToString(), rowNumExp);
}
else
{
// Process Expected Duplicates
string dupExp;
for (int i = 0; i < fieldCount; i++)
{
if (i >= fieldCountExp)
{
dupExp = null;
}
else
{
dupExp = readerCSVExp[i];
}
foreach (int keyColumn in keyColumns)
{
if (i == keyColumn - 1)
{
resultCell = "duplicateEXP: '" + dupExp + "'";
resultCell = CreateCSVField(resultCell);
resultsFile.Write(resultCell);
comSumCol = comSumCol + 1;
countDuplicateExp = countDuplicateExp + 1;
}
else
{
if (checkPTColumns(i + 1, passthroughColumns) == false)
{
resultCell = "'" + dupExp + "'";
resultCell = CreateCSVField(resultCell);
resultsFile.Write(resultCell);
countDuplicateExp = countDuplicateExp + 1;
}
else
{
resultCell = "PASSTHROUGH duplicateEXP: '" + dupExp + "'";
resultCell = CreateCSVField(resultCell);
resultsFile.Write(resultCell);
}
comSumCol = comSumCol + 1;
}
}
if (comSumCol <= fieldCount)
{
resultsFile.Write(csComma);
}
}
if (comSumCol == fieldCount + 1)
{
resultsFile.Write(csComma + rowNumExp);
comSumCol = comSumCol + 1;
}
if (comSumCol == fieldCount + 2)
{
resultsFile.Write(csComma);
comSumCol = comSumCol + 1;
}
if (comSumCol > fieldCount + 2)
{
comSumRow = comSumRow + 1;
resultsFile.Write(csCrLf);
comSumCol = 1;
}
}
keyExp.Clear();
}
logFile.WriteLine("Done Reading Expected File at " + DateTime.Now + "\r\n");
Console.WriteLine("Done Reading Expected File at " + DateTime.Now + "\r\n");
logFile.WriteLine("Done Analyzing Expected Duplicates at " + DateTime.Now + "\r\n");
Console.WriteLine("Done Analyzing Expected Duplicates at " + DateTime.Now + "\r\n");
logFile.Flush();
Tuy nhiên, vấn đề là tôi cần cả bộ dữ liệu trong bộ nhớ. Tôi thực sự lặp qua cả hai từ điển tìm kiếm các kết quả phù hợp, không phù hợp, trùng lặp và bỏ học dựa trên khóa.
Sử dụng phương pháp này để lưu trữ chỉ mục hàng, tôi vẫn đang sử dụng rất nhiều bộ nhớ vì truy cập động tôi phải sử dụng phiên bản được lưu trong bộ nhớ cache của trình đọc csv. Vì vậy, mặc dù từ điển nhỏ hơn nhiều bây giờ, bộ nhớ đệm của dữ liệu bù đắp cho các khoản tiết kiệm và tôi vẫn kết thúc với việc sử dụng bộ nhớ tương tự.
Hope, tôi đang làm cho cảm giác ... :)
Một lựa chọn là để thoát khỏi từ điển hoàn toàn và chỉ cần vòng qua 2 tác phẩm, nhưng không chắc chắn nếu thực hiện sẽ nhanh như so sánh 2 từ điển.
Mọi yếu tố đầu vào đều được đánh giá cao.
thay vì lưu bộ nhớ cache của trình đọc csv, bạn không thể lưu vào bộ nhớ cache vị trí bản ghi trong tệp, để bạn có thể lấy lại các bản ghi sau? khi bạn lặp lại thông qua các từ điển tìm kiếm bỏ học vv bởi chính là bạn nhìn vào dữ liệu thực tế hoặc chỉ là các phím? –
bạn có cố gắng thực hiện chuỗi trước khi chúng đi vào từ điển không? nó có sự khác biệt không? Có bất kỳ điều này đã giúp với việc sử dụng bộ nhớ ở tất cả? –