2016-04-27 35 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仍然昂貴,雖然 –