私はIntensively Listを使用するプロジェクトで作業しています。私は名前(オブジェクトのメンバー)を介してオブジェクトを見つけようとしています。Findとfindindexは厄介なリスト<Object>のために遅い?
私のコードは、1つのfor-nextループ(関数find1)を使用して検索することなく機能しましたが、ビルドインのfind関数を使用して同じことが可能であることがわかりました。しかし、それは少し遅く感じる。
私は次のコード
public List<MyObject> varbig = new List<MyObject>();
public Dictionary<string,string> myDictionary=new Dictionary<string, string>();
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
myDictionary.Clear();
varbig.Clear();
for (int i = 0; i < 5000; i++) {
varbig.Add(new MyObject("name" + i.ToString(),"value"+i.ToString()));
myDictionary.Add("name" + i.ToString(), i.ToString());
}
// first test
var start1 = Environment.TickCount;
for (int i = 0; i < 3000; i++) {
var ss=find1("name499");
}
var end1 = Environment.TickCount;
Console.WriteLine("time 1 :" + (end1 - start1));
// second test
var start2 = Environment.TickCount;
for (int i = 0; i < 3000; i++) {
var ss=find2("name499");
}
var end2 = Environment.TickCount;
Console.WriteLine("time 2 :" + (end2 - start2));
// third test
var start3 = Environment.TickCount;
for (int i = 0; i < 3000; i++) {
var ss = find3("name499");
}
var end3 = Environment.TickCount;
Console.WriteLine("time 3 :" + (end3 - start3));
// first test b
var start1b = Environment.TickCount;
for (int i = 0; i < 3000; i++) {
var ss=find1("name4999");
}
var end1b = Environment.TickCount;
Console.WriteLine("timeb 1 :" + (end1b - start1b));
// second test
var start2b = Environment.TickCount;
for (int i = 0; i < 3000; i++) {
var ss=find2("name4999");
}
var end2b = Environment.TickCount;
Console.WriteLine("timeb 2 :" + (end2b - start2b));
// third test
var start3b = Environment.TickCount;
for (int i = 0; i < 3000; i++) {
var ss = find3("name4999");
}
var end3b = Environment.TickCount;
Console.WriteLine("timeb 3 :" + (end3b - start3b));
}
public int find1(string name) {
for (int i = 0; i < varbig.Count; i++) {
if(varbig[i].Name == name) {
return i;
}
}
return -1;
}
public int find2(string name) {
int idx = varbig.FindIndex(tmpvar => Name == name);
return idx;
}
public int find3(string name) {
var ss=myDictionary[name];
return int.Parse(ss);
}
}
を持っていると私は次のオブジェクト
public class MyObject {
private string _name = "";
private string _value = "";
public MyObject() {}
public MyObject(string name, string value) {
_name = name;
_value = value;
}
public string Name {
get { return _name; }
set { _name = value; }
}
public string Value {
get { return _value; }
set { _value = value; }
}
}
ほとんどが、それは次のことを行うを使用します:私は作成 だから、私はテストのためにプロジェクトの速度をしました5000要素の配列
時間1 =単純なfor-nextを使用して499番目のオブジェクト(インデックス)を検索します。
時間2 =リスト
時間3の関数findでビルドを使用して第四百九十九を検索=それは辞書を使用して第四百九十九要素の検索を行います。
Timeb 1、timeb 2、およびtimeb 3は同じことを行いますが、499番目の要素の代わりに4999番目の要素を検索してみます。
- 時間1:141
- 時間2:1248
- 時間3:0
- TIMEB 1:811
- TIMEB 2:1170 は、私は数回を走りました
時間b 3:0
時間1:109
- 時間2:1170
- 時間3:0
- TIMEB 1:796
- TIMEB 2:1170
- TIMEB 3:0
(小次いで速い)
私の驚きは、機能の組み込みfindindexは非常に遅いです(場合によっては、10倍近く遅くなります)。また、辞書のアプローチはほぼ即座に行われます。
私の質問は、なぜですか?それは述語なのか? Find1はFind2が、あなたはそれと一緒に述語に合格したことを除いて、(上記の正確find1ある)Findメソッドに建て使用しています(I = 0カウントする)ための簡単な方法
タイミングをテストする場合は、「環境」を確認する代わりに['System.Diagnostics.Stopwatch'](http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) .TickCount'。 – Powerlord
このタイプのルックアップを実行する場合は、バランスの取れたツリーの使用を検討する必要があります。 –
ディクショナリを避けるもう1つの方法は、[Array.BinarySearch](http://msdn.microsoft.com/en-us/library/y15ef976.aspx)です。この方法では、まずリスト 'リスト'をソートする必要があります。したがって、 'MyObject'は' IComparable'を実装する必要があります。 –