2016-04-27 55 views
0

所以这个程序的输入是一个447000行的文件,每一行都是可以拆分成第五个列表的数据。这个程序中的什么操作让它变慢?

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

据我了解,我认为每一个操作IM做的是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 

要添加一些我在我的桌面与4GHz的运行4核CPU上运行更多相关信息,该信息被从磁盘读取这是SSD;运行时,任务管理器中的磁盘使用率为0%。我也下车Console.ReadLine并再次运行它吧,然后会做一些秒表基准

解决方案:
它的IndexOf查找这是造成巨大的运行时间,这一切都改变的Parallel.For,只需要大约1.25秒处理

+2

我不知道这是否会产生巨大的变化,但是,你做一个的indexOf - 为什么不循环而不是做的foreach并行..然后你已经拥有的索引。它会保存一个查找 – BugFinder

+1

我不知道,但我认为,这应该更适合于codereview.stackexchange.com –

+0

@MatíasFidemraizer哦不对,我认为你是正确的。我以前没有带起诉的话,会看看 – Toxicable

回答

1

正如上面指出的,INDEXOF在循环,使你的算法中O(N2),这是坏...

你应该考虑的阵列上一个简单的Parallel.For。

+0

对不起,你的意思是一个'Parallel.For'循环? – Toxicable

+2

虽然这是它,但改变为并行。因为它现在有一个约1.25秒的运行时间 – Toxicable

+0

编辑答案。 Console.write仍然昂贵,虽然 –