0

我有一个超级简单的脚本,我用它来将我们多年来从捐赠者那里收集的一长串电话号码分成单独的区号文件。

显然,当你有近 100 万行时,这将需要一段时间 - 但是 - 如果我输入 1,000 行,它只需要不到一秒的时间。一旦我投入 100 万,只需要 10 秒就可以完成 5 行。这怎么可能?

Imports System.IO
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
    BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
    Dim lines As String
    lines = RichTextBox1.Lines.Count
    Dim looper As String = 0
    Dim path As String = "c:\acs\"
    MsgBox("I have " + lines + " lines to do.")
    If (Not System.IO.Directory.Exists(path)) Then
        System.IO.Directory.CreateDirectory(path)
    End If
    Dim i As String = 0

    For loops As Integer = 0 To RichTextBox1.Lines.Count - 1
        Dim ac As String = RichTextBox1.Lines(looper).ToString
        ac = ac.Substring(0, 3)
        Dim strFile As String = path + ac + ".txt"
        Dim sw As StreamWriter
        sw = File.AppendText(strFile)
        sw.WriteLine(RichTextBox1.Lines(looper))
        sw.Close()
        Label1.Text = String.Format("Processing item {0} of {1}", looper, lines)
        looper = looper + 1
    Next
    MsgBox("done now")
End Sub

结束类

4

2 回答 2

0

首先,您在 For 循环中执行 UI 更新。这需要时间。

您正在不是可能影响性能的主线程的线程中更新 UI。您不应使用 CheckForIllegalCrossThreadCalls 方法。您应该使用 BackgroundWorker 的 ReportProgress 方法正确更新 UI。

您正在为循环的每次迭代打开和关闭一个文件。这也需要时间。

我认为更好的方法是将数据添加到 Dictionary(Of String, List(Of String)) 中,以区号为键,列表将包含该区号的所有数字。一旦字典被填满,循环遍历键并写出数字。

于 2013-02-25T16:48:50.047 回答
0

每次使用 RichTextBox.Lines 属性时,VB.Net 都需要通过 CR+LF 对来分割内容。因此,您For loops As Integer = - To RichTextBox1.Lines.Count-1的性能确实很受欢迎。尝试使用:

For Each vsLine As String in RichTextBox1.Lines

反而。它会快很多。或者,如果您必须使用 For 循环,则获取一次:

Dim vasLines() As String = RichTextBox1.Lines
For viLines As Integer = 0 to UBound(vasLines.Count)
    '....
Next

反而。

于 2013-02-23T07:46:56.173 回答