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万行
这需要很长时间:(即使是四核AMD 965超频到4.2 GHZ。
答案 0 :(得分:2)
首先,上述代码无效。 List(Of T)
不是线程安全的,因此从多个线程执行此操作实际上会导致重大问题而不进行同步,因为对Add
和Contains
的调用本身并不安全。多线程。
更好的选择是选择更好的集合,例如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)
),这会导致运行批次< / em>更快,甚至单线程。
如果您不需要存储完成,您可以保留数组,并直接使用Enumerable.Except
(在内部使用Set):
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();
答案 1 :(得分:0)
您可以使用效率更高的Enumerable.Except
,因为它实现为HashSet<T>
:
IEnumerable(Of String) newLines = thinkingofdoing.Except(done)
你也应该使用File.ReadLines
而不是File.ReadAllLines
,因为前者使用流,而后者一次将全部加载到内存中。
我会首先测试性能而不使用ThreadPool
。
答案 2 :(得分: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中,然后不是将完整的文件内容加载到内存中,而是逐行解析,只有在尚未完成时才添加到todo中
如果VB.Net有一个收益率回报,我会把它放在一个函数中并在IEnumerable上完成ToList但是嘿嘿。