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.txtthinkingofdoing.txtには、500 万から 800 万行の行があります。

4.2 GHz にオーバークロックされたクアッド コア AMD 965 を使用しても、非常に時間がかかります。

4

3 に答える 3

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)に高速に実行されます。

Doneを保存する必要がない場合は、配列を保持して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();
于 2012-07-17T16:11:39.197 に答える
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 に yield リターンがあれば、それを関数に入れて IEnumerable で ToList を実行したでしょうが、ほら。

于 2012-07-17T16:27:55.077 に答える
0

Enumerable.Except次のように実装されているため、はるかに効率的なはずの which を使用できますHashSet<T>

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

また、前者はストリームを使用するのに対し、後者はすべてを一度にメモリにロードするため、File.ReadLines代わりに使用する必要があります。File.ReadAllLines

ThreadPool最初に使用せずにパフォーマンスをテストします。

于 2012-07-17T16:11:44.427 に答える