0

さまざまなファイルを RichTextBox にロードし、ドキュメントをスキャンして特定の単語を見つけるために使用する VB.NET アプリケーションがあります。Word の検索機能に似ています。アプリは、5,150 行の .sql ドキュメントが実行されるまで正常に実行され、実行が完了するまでに 10 分以上かかります。

以下のコードよりも優れたコーディング方法を推奨できる人はいますか?

    If sqlText.Contains("GRANT") Then

        Dim searchstring As String = "GRANT"

        Dim count As New List(Of Integer)()

        For i As Integer = 0 To rtbFile.Text.Length - 1
            If rtbFile.Text.IndexOf(searchstring, i) <> -1 Then
                count.Add(rtbFile.Text.IndexOf(searchstring, i))
            End If
        Next

        Try
            For i As Integer = 0 To count.Count - 1
                rtbFile.Select(count(i), searchstring.Length)
                rtbFile.SelectionBackColor = Color.Yellow
                rtbFile.SelectionFont = New Font(rtbFile.Font, FontStyle.Bold)
                count.RemoveAt(i)
            Next
        Catch ex As Exception
        End Try

        rtbFile.Select(rtbFile.Text.Length, 0)
        rtbFile.SelectionBackColor = Color.White
        rtbFile.SelectionFont = New Font(rtbFile.Font, FontStyle.Regular)

    End If
4

4 に答える 4

1

おっと。IndexOf に関する非常に重要なポイントを見逃していました (そして、前回の試合の終わりにフィードされたと誤って想定していました)。マグナスの答えを参照してください。


ボトルネックがどこにあるのかはわかりませんが(選択自体の設定に起因する可能性が非常に高い)、おおまかに優先順位の高い順に以下に提案します。

  1. rtbFile.Text を 1 回呼び出して、基になるコントロール(おそらくネイティブ Windows コントロール?) へのラウンドトリップを回避し、変数を使用して結果の文字列を格納します。文字列が .NET で取得されたら、テキストが変更されない限り/変更されるまで直接使用し続けます。コントロールがネイティブの場合、単純に「テキストを取得」するために多くの作業が必要になる場合があります。

  2. カウント コレクションに対して通常の項目反復を使用し (インデックス作成ではありません)、選択を割り当てるときにリストの先頭から削除しないでください。List の先頭からの削除は、すべてのアイテムを内部的に下に移動する必要があるという点で「費用がかかります」。また、ここで要素を削除する必要はなく、せいぜい疑わしいです: 変更されているコレクションも反復されているため、パフォーマンスに関係なく、誤った動作 (スキップされた項目) につながる可能性があります。

  3. ループごとに 1 回だけ IndexOf を呼び出し、変数を使用して重複検索を回避します。これはおそらく全体的な影響はありませんが、「余分な」作業を回避します。IndexOf 自体は問題なく、置き換える必要はありません。

YMMV。

于 2013-09-30T19:35:11.310 に答える