Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 有没有一种更快的方法可以从一个字符串列表中减去另一个字符串列表_Vb.net_String_List - Fatal编程技术网

Vb.net 有没有一种更快的方法可以从一个字符串列表中减去另一个字符串列表

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

done.txtthinkingofdoing.txt有500万到800万行


这需要很长时间:(,即使是四核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