3 回答

TA貢獻1784條經驗 獲得超2個贊
雖然您可以進行許多小的優化,但真正讓您喪命的是垃圾收集器,因為所有的分配。
你的代碼在我的機器上運行需要 12 秒。讀取文件使用了這 12 秒中的 2 秒。
通過使用評論中提到的所有優化(使用File.ReadLines, StringSplitOptions.RemoveEmptyEntries,也使用float.Parse(f, CultureInfo.InvariantCulture)而不是調用string.Replace),我們將時間縮短到 9 秒。仍有很多分配已完成,尤其是File.ReadLines. 我們能做得更好嗎?
只需在 app.config 中激活服務器 GC:
<runtime>
<gcServer enabled="true" />
</runtime>
這樣,使用您的代碼執行時間下降到 6 秒,使用上述優化后執行時間下降到 3 秒。那時,文件 I/O 占用了超過 60% 的執行時間,因此不值得進一步優化。
代碼的最終版本:
var lines = File.ReadLines(filePath);
var separator = new[] {','};
var result = lines.AsParallel().AsOrdered().Select((line, index) =>
{
var values = line?.Split(separator, StringSplitOptions.RemoveEmptyEntries)
.Select(f => float.Parse(f, CultureInfo.InvariantCulture)).ToArray();
return (index, values);
}).ToDictionary(d => d.Item1, d => d.Item2);

TA貢獻1772條經驗 獲得超8個贊
用手動解析替換SplitandReplace并使用InvariantInfo接受句點作為小數點,然后刪除浪費ReadAllLines().ToList()并AsParallel()在解析時從文件中讀取,在我的 PC 上加速了大約四倍。
var lines = File.ReadLines(filepath);
var result = lines.AsParallel().AsOrdered().Select((line, index) => {
var values = new List<float>(10000);
var pos = 0;
while (pos < line.Length) {
var commapos = line.IndexOf(',', pos);
commapos = commapos < 0 ? line.Length : commapos;
var fs = line.Substring(pos, commapos - pos);
if (fs != String.Empty) // remove if no value is ever missing
values.Add(float.Parse(fs, NumberFormatInfo.InvariantInfo));
pos = commapos + 1;
}
return values;
}).ToList();
也用 a代替ToArray,因為它通常更快(優于)。valuesListToListToArray

TA貢獻1779條經驗 獲得超6個贊
using Microsoft.VisualBasic.FileIO;
protected void CSVImport(string importFilePath)
{
string csvData = System.IO.File.ReadAllText(importFilePath, System.Text.Encoding.GetEncoding("WINDOWS-1250"));
foreach (string row in csvData.Split('\n'))
{
var parser = new TextFieldParser(new StringReader(row));
parser.HasFieldsEnclosedInQuotes = true;
parser.SetDelimiters(",");
string[] fields;
fields = parser.ReadFields();
//do what you need with data in array
}
}
- 3 回答
- 0 關注
- 115 瀏覽
添加回答
舉報