正規表現を使った場合と使わない場合の処理速度を比較します。
正規表現を使う場合のアルゴリズムは「CSVファイルを読み込んでDataGridに表示」の DataTable GetCsvDataTable(string content) メソッドを、
使わない場合のアルゴリズムは「正規表現を使わないでCSVをパース」の DataTable GetCsvDataTable(string content) メソッドを使ってます。
下のソースでは、それぞれのメソッド名を、GetCsvDataTableRegex、GetCsvDataTableNoRegex に変更しています。
「Task.Factory.StartNew で 非同期処理」の方法で、2つのCSVのパースを並列処理し、処理時間をテキストボックスに表示します。
左が正規表現を使った場合、右が使わない場合です。
正規表現を使わないアルゴリズムの方が5倍ほど速いようです。
テストデータは、市町村コードをコピーして10万行くらいに増やしています。
MainWindow.xaml
<Window x:Class="WpfApplication3.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="350" Width="625">
<Window.CommandBindings>
<CommandBinding Command="Open" Executed="OpenCommandHandler"/>
</Window.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Command="Open" />
</Menu>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" Name="dataGrid1" />
<TextBox Grid.Row="1" Name="textBox1"
Text="{Binding Path=StatusAndElapsedTime,Mode=OneWay}"
TextChanged="textBox1_TextChanged" />
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" Name="dataGrid2" />
<TextBox Grid.Row="1" Name="textBox2"
Text="{Binding Path=StatusAndElapsedTime,Mode=OneWay}"
TextChanged="textBox2_TextChanged" />
</Grid>
</Grid>
</Grid>
</Window>
MainWindow.xaml.cs
using Microsoft.Win32;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
namespace WpfApplication3
{
public partial class MainWindow : Window
{
private Message message1 = new Message();
private Message message2 = new Message();
private Task<DataTable> task1;
private Task<DataTable> task2;
public MainWindow()
{
InitializeComponent();
this.textBox1.DataContext = this.message1;
this.textBox2.DataContext = this.message2;
}
private void OpenCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
string content = File.ReadAllText(ofd.FileName, Encoding.GetEncoding("Shift_JIS"));
this.dataGrid1.ItemsSource = null;
this.dataGrid2.ItemsSource = null;
this.message1.Status = TaskStatus.Created;
this.message2.Status = TaskStatus.Created;
task1 = Task.Factory.StartNew(() => GetCsvDataTableRegex(content, this.message1));
task2 = Task.Factory.StartNew(() => GetCsvDataTableNoRegex(content, this.message2));
}
}
private static DataTable GetCsvDataTableNoRegex(string content,Message message)
{
message.Status = TaskStatus.Running;
// ・・・・・・・・・・・
// ・・・・・・・・・・・
// ・・・・・・・・・・・
message.Status = TaskStatus.RanToCompletion;
return dt;
}
private static DataTable GetCsvDataTableRegex(string content,Message message)
{
message.Status = TaskStatus.Running;
// ・・・・・・・・・・・
// ・・・・・・・・・・・
// ・・・・・・・・・・・
message.Status = TaskStatus.RanToCompletion;
return dt;
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
if (this.message1.Status == TaskStatus.RanToCompletion)
{
dataGrid1.ItemsSource = task1.Result.DefaultView;
}
}
private void textBox2_TextChanged(object sender, TextChangedEventArgs e)
{
if (this.message2.Status == TaskStatus.RanToCompletion)
{
dataGrid2.ItemsSource = task2.Result.DefaultView;
}
}
}
}
Message.cs
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading.Tasks;
namespace WpfApplication3
{
public class Message : INotifyPropertyChanged
{
public Stopwatch Stopwatch { get; set; }
private TaskStatus status = TaskStatus.Created;
public TaskStatus Status
{
get { return status; }
set
{
if (value != this.status)
{
if (value == TaskStatus.RanToCompletion)
{
this.Stopwatch.Stop();
}
else if (value == TaskStatus.Running)
{
this.Stopwatch.Restart();
}
this.status = value;
NotifyPropertyChanged("Status");
NotifyPropertyChanged("StatusAndElapsedTime");
}
}
}
public string StatusAndElapsedTime
{
get
{
return this.status + "\n" +
((this.status == TaskStatus.RanToCompletion) ? this.Stopwatch.Elapsed.ToString() : "");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public Message()
{
this.Stopwatch = new Stopwatch();
}
}
}
0 件のコメント:
コメントを投稿