快速阅读大表

时间:2019-04-19 23:22:03

标签: c# multithreading csv

我的csv文件结构如下:

<template>
  <v-navigation-drawer
    v-model="visible"
    fixed
    app
    dark
    class="primary"
  >
    <v-toolbar flat class="ap-img-toolbar">
      <v-list class="pa-0">
        <v-list-tile>
          <v-list-tile-action>
            <img src="/images/LogoSmall.png">

          </v-list-tile-action>
        </v-list-tile>
      </v-list>
    </v-toolbar>

    <TheLeftSidebarAppList />

  </v-navigation-drawer>
</template>

,但具有10k列和10k行。 我想以这样的方式阅读它,结果得到一本字典 其中Key是该行的索引,而Value是该行中包含每个值的float数组。  现在,我的代码如下:

1,0,2.2,0,0,0,0,1.2,0
0,1,2,4,0,1,0.2,0.1,0
0,0,2,3,0,0,0,1.2,2.1
0,0,0,1,2,1,0,0.2,0.1
0,0,1,0,2.1,0.1,0,1.2
0,0,2,3,0,1.1,0.1,1.2
0,0.2,0,1.2,2,0,3.2,0
0,0,1.2,0,2.2,0,0,1.1

但是它最多需要30秒才能完成,所以它很慢,我想对其进行优化使其更快。

3 个答案:

答案 0 :(得分:4)

虽然您可以进行许多小的优化,但是由于所有分配,真正使您丧命的是垃圾收集器。

您的代码需要12秒钟才能在我的计算机上运行。读取文件需要使用这12秒钟中的2秒钟。

通过使用注释中提到的所有优化(使用File.ReadLinesStringSplitOptions.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);

答案 1 :(得分:3)

通过手动解析替换<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="divs_in_cols.css"> </head> <body> <div class="container"> <div class="download"> <h1> This Is The Title 1 </h1> <p> Desc 1 </p> <p> Realeased */*/* </p> <br> <a class="button" href="#">Download</a> </div> <div class="download"> <h1> This Is The Title 2 </h1> <p> Desc 2 </p> <p> Realeased */*/* </p> <br> <a class="button" href="#">Download</a> </div> <div class="download"> <h1> This Is The Title 3 </h1> <p> Desc 3 </p> <p> Realeased */*/* </p> <br> <a class="button" href="#">Download</a> </div> <div class="download"> <h1> This Is The Title 4 </h1> <p> Desc 4 </p> <p> Realeased */*/* </p> <br> <a class="button" href="#">Download</a> </div> </div> </body> </html>df.group(['interval'],,as_index=False).agg({ 'a':{"count":"mean"}, 'b':{"count":"mean"}, 'c':{"count":"mean"}, 'd':{"count":"mean"}, 'f':{"count":"mean"}, 'g':{"count":"mean"}, 'i':{"count":"mean"} }) ,并使用Split接受句点作为小数点,然后删除浪费的Replace并让{{1 }}解析时从文件读取,在我的PC上速度提高了大约四倍。

InvariantInfo

还用ReadAllLines().ToList()替换了AsParallel()上的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(); ,因为这样通常更快(ToArrayvalues优先)。

答案 2 :(得分:-3)

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
            }

        }