ken のすべての投稿

.NETからWindows APIを使用する際の便利サイト

C#やVB.NETで開発をしていて、それほど頻度がある訳ではないのですが
Windows APIを直接使用しないとできないような機能があります。

例えば、EXCELファイルをC#で作成してそのウィンドウを前面に
表示させたい等、他のプロセスのウィンドウを操作する場合です。

こういったときによく利用させていただいているサイトがあります。

http://pinvoke.net/index.aspx

です。数が膨大なので全部確認している訳ではないのですが、大体のAPIは
ここにありそうです。

参考になれば幸いです。

[C#] 開発メモ クラス検索のパフォーマンスについて

現在開発中のC#のプロジェクトで静的フィールドのメモリ内に
リストを持ち、必要に応じてメモリのリストよりクラスを検索して
返しているロジックがあります。

この検索ロジックですが、List<T>で持っており、LINQのwhere句で
検索を行っています。

もし遅いようであれば、リストをSortedListを使うなり、ListのBinarySearch
を利用することで対応しようと思っていたのですが、せっかくなので
多めのテストデータを使ってパフォーマンステストを実施してみました。

ここでデータは予めソートされていることを前提とします。

先に比較結果を記述します。

[リストへ100,000件追加]
List型(1回目):0.234秒
List型(2回目):0.234秒
List型(3回目):0.218秒
SortedList型(1回目):1.093秒
SortedList型(2回目):1.125秒
SortedList型(3回目):1.171秒

[100,000件から1件のレコードを1,000回検索]
List型(LINQのwhere句)(1回目):51.312秒
List型(LINQのwhere句)(2回目):51.171秒
List型(LINQのwhere句)(3回目):51.093秒
List型(BinarySearch)(1回目):0.015秒
List型(BinarySearch)(2回目):0.015秒
List型(BinarySearch)(3回目):0.015秒
SortedList型(1回目):0.015秒
SortedList型(2回目):0.015秒
SortedList型(3回目):0.015秒

この結果を見る限り、利用するならリストへの追加、検索の
ともに速いList型のBinarySearchがよさそうです。

ただ、ここでは1レコードを取得するテストを行いましたが
実際のプロジェクトでは範囲検索でリストを取得する処理も
行っているので、若干工夫が必要になりそうです。

ちなみにSortedList型でLINQを使って同じように検索すると
53.062秒と遅くなりました。LINQを使う場合はSortedListにしても
変わりはないようです・・・

参考までにテストの際に使用したソースを以下に記述します。

[検索するクラス]
public class Table
{
public String Key1 { get; set; }
public String Key2 { get; set; }
public String Key3 { get; set; }
public String Key4 { get; set; }
public String Key5 { get; set; }
public String Value { get; set; }
}

[比較用クラス]
public class TableCompare : IComparer<Table>
{
public int Compare(Table x, Table y)
{
if (x.Key1 != y.Key1)
{
return String.Compare(x.Key1, y.Key1);
}
if (x.Key2 != y.Key2)
{
return String.Compare(x.Key2, y.Key2);
}
if (x.Key3 != y.Key3)
{
return String.Compare(x.Key3, y.Key3);
}
if (x.Key4 != y.Key4)
{
return String.Compare(x.Key4, y.Key4);
}
return String.Compare(x.Key5, y.Key5);
}
}

リストへの追加処理

[List型]
List<Table> lstTable = new List<Table>();
for (Int32 i = 0; i < 100000; i++)
{
Table table = new Table();
table.Key1 = “1”;
table.Key2 = “2”;
table.Key3 = “3”;
table.Key4 = “4”;
table.Key5 = String.Format(“{0:00000}”, i);
table.Value = i.ToString();
lstTable.Add(table);
}

[SortedList型]
SortedList<Table, Table> slstTable = new SortedList<Table, Table>(new TableCompare());
for (Int32 i = 0; i < 100000; i++)
{
Table table = new Table();
table.Key1 = “1”;
table.Key2 = “2”;
table.Key3 = “3”;
table.Key4 = “4”;
table.Key5 = String.Format(“{0:00000}”, i);
table.Value = i.ToString();
slstTable.Add(table, table);
}

検索の比較

[List型(LINQのwhere句)]
for (Int32 i = 0; i < 1000; i++)
{
Random rm = new Random(i);
Int32 key = rm.Next(100000);

Table table = lstTable.Where(m =>
m.Key1 == “1”
&& m.Key2 == “2”
&& m.Key3 == “3”
&& m.Key4 == “4”
&& m.Key5 == String.Format(“{0:00000}”, key))
.FirstOrDefault();
}

[List型(BinarySearch)]
for (Int32 i = 0; i < 1000; i++)
{
Random rm = new Random(i);
Int32 key = rm.Next(100000);

Table tableKey = new Table();
tableKey.Key1 = “1”;
tableKey.Key2 = “2”;
tableKey.Key3 = “3”;
tableKey.Key4 = “4”;
tableKey.Key5 = String.Format(“{0:00000}”, key);

Int32 index = lstTable.BinarySearch(tableKey, new TableCompare());
Table table = lstTable[index];
}

[SortedList型]
for (Int32 i = 0; i < 1000; i++)
{
Random rm = new Random(i);
Int32 key = rm.Next(100000);

Table tableKey = new Table();
tableKey.Key1 = “1”;
tableKey.Key2 = “2”;
tableKey.Key3 = “3”;
tableKey.Key4 = “4”;
tableKey.Key5 = String.Format(“{0:00000}”, key);

Table table = slstTable[tableKey];
}