亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

快讀大表。

快讀大表。

C#
慕工程0101907 2022-12-24 10:18:03
我的 csv 文件結構如下:1,0,2.2,0,0,0,0,1.2,00,1,2,4,0,1,0.2,0.1,00,0,2,3,0,0,0,1.2,2.10,0,0,1,2,1,0,0.2,0.10,0,1,0,2.1,0.1,0,1.20,0,2,3,0,1.1,0.1,1.20,0.2,0,1.2,2,0,3.2,00,0,1.2,0,2.2,0,0,1.1但有 10k 列和 10k 行。我想以這樣的方式閱讀它,在結果中我得到一個字典,其中 Key 作為行的索引,Value 作為 float 數組,其中包含該行中的每個值?,F在我的代碼看起來像這樣: var lines = File.ReadAllLines(filePath).ToList(); var result = lines.AsParallel().AsOrdered().Select((line, index) => {    var values = line?.Split(',').Where(v =>!string.IsNullOrEmpty(v))         .Select(f => f.Replace('.', ','))               .Select(float.Parse).ToArray();    return (index, values);       }).ToDictionary(d => d.Item1, d => d.Item2);但它最多需要 30 秒才能完成,所以它很慢,我想優化它以使其更快一些。
查看完整描述

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);


查看完整回答
反對 回復 2022-12-24
?
料青山看我應如是

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


查看完整回答
反對 回復 2022-12-24
?
哆啦的時光機

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

            }


        }


查看完整回答
反對 回復 2022-12-24
  • 3 回答
  • 0 關注
  • 115 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號