2012-07-17 101 views
1
Public done As New List(Of String) 
Public thinkingofdoing As New List(Of String) 
Public todo As New List(Of String) 

done.AddRange(System.IO.File.ReadAllLines("C:\Users\Work\Desktop\done.txt")) 
thinkingofdoing.AddRange(System.IO.File.ReadAllLines("C:\Users\Work\Desktop\thinkingofdoing.txt")) 

For i = 0 To thinkingofdoing.Count - 1 
    ThreadPool.QueueUserWorkItem(AddressOf caldiff, thinkingofdoing(i)) 
Next 

Public Sub caldiff(ByVal tobedone) 
    If done.Contains(tobedone) = False Then 
     todo.Add(tobedone) 
    End If 
End Sub 

done.txt字符串。減去一個列表thinkingofdoing.txt有500萬至任何地方800萬線vb.net是否有從另一個

它採取非常長的更快的方法和:(即使是四核AMD 965超頻到了4.2 GHz)

+0

您正在使用非線程安全集合的線程池。解決這個問題不會解決你的性能問題,但它可能會防止稍後的微妙錯誤。 – vcsjones 2012-07-17 16:12:04

回答

2

首先,上面的代碼是無效的List(Of T)不是線程安全的,因此從多線程執行這個操作實際上會導致沒有同步的重大問題,因爲撥打AddContains本身並不安全,可以從多個線程中調用。

更好的選擇是選擇更好的集合,如HashSet(Of T),這會使檢查速度加快。我建議是這樣的:

public Done as New HashSet(Of String) 
public ThinkingOfDoing as IList(Of String) 
public Todo as New List(Of String) 

ThinkingOfDoing = System.IO.File.ReadAllLines("C:\Users\Work\Desktop\thinkingofdoing.txt") 
Done.AddRange(System.IO.File.ReadAllLines("C:\Users\Work\Desktop\done.txt")) 

ToDo = ThinkingOfDoing.Where(Function(i) Done.Contains(i) = False).ToList() 

通過使用HashSet(Of T),該Contains()檢查將成爲遠快(而不是O(1)O(n)),這將導致此運行很多更快,甚至單線程的。

如果您不需要完成,你可以只保留陣列,並直接使用Enumerable.Except(它使用一組內部):

ThinkingOfDoing = System.IO.File.ReadAllLines("C:\Users\Work\Desktop\thinkingofdoing.txt") 
Dim done = System.IO.File.ReadAllLines("C:\Users\Work\Desktop\done.txt") 

Dim Todo = ThinkingOfDoing.Except(done).ToList(); 
+0

最後一位代碼對所有內容進行排序。可能需要15-20小時的時間在15秒內完成。非常感謝 – novicecoder 2012-07-17 16:19:11

0

您可以使用Enumerable.Except這應該是多少更有效,因爲它的實現爲HashSet<T>

IEnumerable(Of String) newLines = thinkingofdoing.Except(done) 

您還應該使用File.ReadLines代替File.ReadAllLines因爲前者使用流而後者一次加載到內存中。

我會首先測試性能而不使用ThreadPool

0

這個怎麼樣...

Public done As ISet(Of String) 
Public toDo As New List(Of String)(); 

done = New HashSet(Of String) _ 
    (System.IO.File.ReadAllLine("C:\Users\Work\Desktop\done.txt") 

Using reader As New StreamReader(New FileStream _ 
     ("C:\Users\Work\Desktop\thinkingofdoing.txt"), FileMode.Open) 
    Do While reader.Peek() >= 0 
     Dim line = reader.ReadLine() 
     If Not done.Contains(line) Then 
      toDo.Add(line) 
     EndIf 
    Loop 
End Using 

這一切做線加載到其具有優良的查找性能HashSet的,然後而不是加載整個做文件到內存的思維就被解析線如果它還沒有完成,只能添加到待辦事項。

如果VB.Net有一個收益率回報,我會把它放在一個函數中,並在IEnumerable上完成ToList,但是嘿嘿。

相關問題