1

ログ ファイルの行を表示するプログラムがあります。

それらは解析され、LogLine というクラスに入れられ、データグリッドに表示されます。

これが私のフィルター関数です:

ICollectionView view = CollectionViewSource.GetDefaultView(this.LogView.ItemsSource);
bool traceChecked = this.TraceCheckbox.IsChecked.HasValue &&     this.TraceCheckbox.IsChecked.Value;
bool debugChecked = this.DebugCheckbox.IsChecked.HasValue && this.DebugCheckbox.IsChecked.Value;
bool infoChecked = this.InfoCheckbox.IsChecked.HasValue && this.InfoCheckbox.IsChecked.Value;
bool warnChecked = this.WarnCheckbox.IsChecked.HasValue && this.WarnCheckbox.IsChecked.Value;
bool errorChecked = this.ErrorCheckbox.IsChecked.HasValue && this.ErrorCheckbox.IsChecked.Value;
string filtertext = this.TextFilterBox.Text;
view.Filter = o =>
    {
        LogLine line = o as LogLine;
        return line != null
               && (((traceChecked && line.Trace) 
               || (debugChecked && line.Debug) 
               || (infoChecked && line.Info) 
               || (warnChecked && line.Warn) 
               || (errorChecked && line.Error))
               && line.Message.Contains(filtertext));
    };

この関数は既に遅く、200000 行のログで 5 秒近くかかります。

これをスピードアップするために何ができますか?

HighCore の提案に従って、実際の ViewModel を実装しました。これはわずかに高速ですが、ObservableCollection のすべての行をスローするのにまだ 5 ~ 6 秒かかります。

ICollectionView view = CollectionViewSource.GetDefaultView(this.LogView.ItemsSource);
LogViewModel lvm = (LogViewModel)this.DataContext;
view.Filter = o =>
    {
        LogLine line = o as LogLine;
        if (line == null || !line.Message.Contains(lvm.FilterText))
            {
                return false;
            }

            switch (line.LogLevel)
            {
                case LogViewModel.LogLevel.Trace:
                    return lvm.Trace;
                case LogViewModel.LogLevel.Debug:
                    return lvm.Debug;
                case LogViewModel.LogLevel.Info:
                    return lvm.Info;
                case LogViewModel.LogLevel.Warn:
                    return lvm.Warn;
                case LogViewModel.LogLevel.Error:
                    return lvm.Error;
                default:
                    return false;
            }
        };
4

1 に答える 1

1

同様のログ ビューアー アプリを作成しましたが、別のアプローチを使用しました。

LogLine のようなクラスへの初期解析を実行し、それらをリストに格納します。次に、ユーザーがさまざまなフィルターの組み合わせを選択すると、Linq を使用して、項目コントロール (私の場合は ListView) にバインドされたフィルター一致の IEnumerable を作成します。必要に応じて、ObservableCollection を使用し、同じ結果をクリア/入力することもできます。

31MB ファイル (240k 行) でテストしたところ、フィルターを変更すると結果が 1 秒以内に表示されます。

于 2013-02-26T14:43:04.133 に答える