这个程序中的哪些操作使它变得如此之慢?

时间:2016-04-27 07:23:27

标签: c#

因此该程序的输入是一个447000行的文件,每行是可以拆分为legnth 5列表的数据。

在当前状态下处理需要大约30分钟,之前我将其作为非平行的foreach循环,但需要花费很长时间才能处理(我没有时间花费多长时间来处理虽然),我真的不确定我是否节省了很多时间,但让它并行运行。所以基本上我不确定什么操作会花费这么长时间来处理,或者如何找到一个。我尝试使用诊断工具,但这并不准确,说一切都是1毫秒。

据我所知,我认为我所做的每一项操作都是O(1)所以如果那是真的那么它的运行速度是否可以呢?

double bytesTransferred = 0;
double firstTimeValue = 0;
double lastTimeValue = 0;
double totalTimeValue = 0;
var dataAsList =  data.ToList();
var justTheTimeDifferences = new ConcurrentBag<double>();
var senderHostsHash = new ConcurrentBag<double>();
var receiverHostsHash = new ConcurrentBag<double>();
var sourcePortsHash = new ConcurrentBag<double>();
var destinationPortsHash = new ConcurrentBag<double>();
int lastPosition = dataAsList.Count;

 Parallel.ForEach(dataAsList, item =>
{
    var currentIndex = dataAsList.IndexOf(item);
    Console.WriteLine($"{currentIndex}/{lastPosition}");

    var itemAsList = item.Split(' ');
    if (dataAsList.IndexOf(item) == 0)
    {
        bytesTransferred += Convert.ToDouble(itemAsList[5]);
        return;
    }

    if (currentIndex == lastPosition - 1)
    {
        lastTimeValue = Convert.ToDouble(itemAsList[0]);
        totalTimeValue = lastTimeValue - firstTimeValue;
    }

    bytesTransferred += Convert.ToDouble(itemAsList[5]);
    var currentTime = Convert.ToDouble(itemAsList[0]);
    var lastEntry = dataAsList[currentIndex - 1];

    justTheTimeDifferences.Add(currentTime - Convert.ToDouble(lastEntry.Split(' ')[0]));
    senderHostsHash.Add(Convert.ToDouble(itemAsList[1]));
    receiverHostsHash.Add(Convert.ToDouble(itemAsList[2]));
    sourcePortsHash.Add(Convert.ToDouble(itemAsList[3]));
    destinationPortsHash.Add(Convert.ToDouble(itemAsList[4]));
});

示例输入是:

0.000000 1 2 23 2436 1  
0.010445 2 1 2436 23 2  
0.023775 1 2 23 2436 2  
0.026558 2 1 2436 23 1  
0.029002 3 4 3930 119 42  
0.032439 4 3 119 3930 15  
0.049618 1 2 23 2436 1 

要添加更多信息,我在桌面上运行此信息,4核CPU以4GHz运行,信息正在从磁盘上读取,这是一个SSD;运行它时,任务管理器中的磁盘使用率为0%。我现在也放弃了Console.ReadLine并再次运行它,然后会做一些秒表基准测试

解决方案:
正是IndexOf查找引起了巨大的运行时间,将其全部更改为Parallel.For并且只需要大约1.25秒来处理

1 个答案:

答案 0 :(得分:1)

如上所述,循环中的Indexof使你的算法成为O(n2),这是不好的......

你应该在数组上考虑一个简单的parallel.for。