更有效的日志过滤器

时间:2013-02-25 14:28:24

标签: wpf performance filtering processing-efficiency

我有一个显示日志文件中的行的程序。

它们被解析并放入一个名为LogLine的类中,然后显示在datagrid

这是我的过滤功能:

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。这稍快一点,但是仍然需要5-6秒才能抛出ObservableCollection的所有行

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;
            }
        };

1 个答案:

答案 0 :(得分:1)

我写了一个类似的日志查看器应用程序,但使用了不同的方法。

我对像LogLine这样的类执行初始解析并将它们存储在列表中。然后,当用户选择各种过滤器组合时,我使用Linq构建一个IEnumerable过滤器匹配项,它绑定到一个项目控件(在我的例子中是一个ListView)。如果您愿意,可以使用ObservableCollection并使用相同的结果清除/填充。

我刚刚测试了31MB文件(240k行),更改过滤器时结果会在一秒钟内显示。