Vb.net 有没有一种更快的方法可以从一个字符串列表中减去另一个字符串列表
done.txt和thinkingofdoing.txt有500万到800万行Vb.net 有没有一种更快的方法可以从一个字符串列表中减去另一个字符串列表,vb.net,string,list,Vb.net,String,List,done.txt和thinkingofdoing.txt有500万到800万行 这需要很长时间:(,即使是四核AMD965超频到4.2GHz。首先,上面的代码是无效的。List(Of T)不是线程安全的,因此从多个线程执行此操作实际上会在没有同步的情况下导致重大问题,因为从多个线程调用Add和Contains本身并不安全 更好的选择是选择更好的集合,例如HashSet(Of T),这将导致检查速度更快。我建议如下: Public done As New List(Of String) Publi
这需要很长时间:(,即使是四核AMD965超频到4.2GHz。首先,上面的代码是无效的。
List(Of T)
不是线程安全的,因此从多个线程执行此操作实际上会在没有同步的情况下导致重大问题,因为从多个线程调用Add
和Contains
本身并不安全
更好的选择是选择更好的集合,例如HashSet(Of T)
,这将导致检查速度更快。我建议如下:
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
通过使用HashSet(Of T)
,Contains()
检查将变得更快(O(1)
,而不是O(n)
),这将导致运行速度更快,甚至是单线程
如果不需要存储Done,可以保留数组,并使用可枚举。除了直接使用
(在内部使用集合)之外:
您可以使用更高效的方法,因为它是作为HashSet
实现的:
您还应该使用File.ReadLines
而不是File.ReadAllLines
,因为前者使用流,而后者一次将所有数据加载到内存中
我会先测试性能而不使用ThreadPool
。这个怎么样
IEnumerable(Of String) newLines = thinkingofdoing.Except(done)
这会将所有完成的行加载到一个具有出色查找性能的HashSet中,然后不再将执行文件的整个思想加载到内存中,而是逐行解析,并且只有在尚未完成时才添加到todo中
如果VB.Net有一个收益率返回,我会把它放在一个函数中,并在IEnumerable上列出,但是嘿嘿,你正在使用线程池和非线程安全的集合。修复它不会修复你的性能,但它可能会防止以后出现细微的错误。最后一段代码对所有内容进行了排序。可能会发生什么花15-20小时在15秒内完成。非常感谢
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();
IEnumerable(Of String) newLines = thinkingofdoing.Except(done)
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