高效的方法来解析大文本文件并处理其中的数据

时间:2016-03-13 12:29:08

标签: c# parsing text-files

大家。 我想解析300 + Mb文本文件,其中包含2.000.000+行,并使用存储的数据进行一些操作(拆分每行,进行比较,在dict中保存数据)。 程序需要大约50分钟才能得到预期的结果(对于80.000行的文件大约需要15-20秒) 有没有办法让它更快地工作? 代码示例如下:

using (FileStream cut_file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (BufferedStream bs = new BufferedStream(cut_file))
            using (StreamReader s_reader = new StreamReader(bs)) {
            string line;
                while ((line = s_reader.ReadLine()) != null) {
                    string[] every_item = line.Split('|'); //line sample: jdsga237 | 3332, 3223, 121 |
                    string car = every_item[0];
                    string[] cameras = every_item[1].Split(',');
                    if (!cars.Contains(car)) { //cars is List<string> defined at the beginning of programm
                        for (int camera = 0; camera < cameras.Count(); camera++) {
                            if (cams_input.Contains(cameras[camera])) { //cams_input is List<string> defined at the beginning of programm
                                cars.Add(car); 
                                result[myfile]++; //result is Dictionary<string, int>. Used dict. for parsing several files.
                            }
                        }
                    }
                }
            }

1 个答案:

答案 0 :(得分:1)

嗯,你很可能遇到与内存使用相关的问题。 但是,在无用的Linq使用中,你有一些明显的低效率: 当你在List上调用Contains()时,你基本上就在List上做一个foreach。

因此,对代码的改进是使用HashSet而不是List来加速Contains()。

在for循环中调用数组上的Count()相同。它是一个数组,所以只需调用Array.Length。

无论如何,你应该在你的机器中分析代码(我使用JetBrains Profiler并发现它非常有价值来进行这种性能分析)。

我对此的看法:

        string myfile = "";
        var cars = new HashSet<string>();
        var cams_input = new HashSet<string>();
        var result = new Dictionary<string, int>();
        foreach (var line in System.IO.File.ReadLines(myfile, System.Text.Encoding.UTF8))
        {
            var everyItem = line.Split('|'); //line sample: jdsga237 | 3332, 3223, 121 |
            var car = everyItem[0];
            if (cars.Contains(car)) continue;

            var cameras = everyItem[1].Split(',');

            for (int camera = 0; camera < cameras.Length; camera++)
            {
                if (cams_input.Contains(cameras[camera]))
                {
                    cars.Add(car);
                    // I really don't get who is inserting value zero.
                    result[myfile]++;
                }
            }
        }

编辑:根据您的评论,性能似乎与列表的使用有关。您应该阅读有关.Net框架中可用集合的指南,如下所示:http://www.codethinked.com/an-overview-of-system_collections_generic 每种类型最适合某种类型的任务:例如,HashSet用于存储唯一值的集合(doh!),它给你的真正闪亮的壮举是O(1)包含操作。 你付出的是哈希的存储和计算。 你也失去了排序等等。

字典基本上是一个HashSet,其值附加到每个键。

好好学习!

Ps:如果问题解决了,请关闭问题。

相关问题