なぜ辞書はリストより速いのか?
2023-09-17 07:46:51
疑問点
Dictionary VSのリストからデータを取得する速度をテストしています。
私はテストするために、このコードを使用しています。
internal class Program
{
private static void Main(string[] args)
{
var stopwatch = new Stopwatch();
List<Grade> grades = Grade.GetData().ToList();
List<Student> students = Student.GetStudents().ToList();
stopwatch.Start();
foreach (Student student in students)
{
student.Grade = grades.Single(x => x.StudentId == student.Id).Value;
}
stopwatch.Stop();
Console.WriteLine("Using list {0}", stopwatch.Elapsed);
stopwatch.Reset();
students = Student.GetStudents().ToList();
stopwatch.Start();
Dictionary<Guid, string> dic = Grade.GetData().ToDictionary(x => x.StudentId, x => x.Value);
foreach (Student student in students)
{
student.Grade = dic[student.Id];
}
stopwatch.Stop();
Console.WriteLine("Using dictionary {0}", stopwatch.Elapsed);
Console.ReadKey();
}
}
public class GuidHelper
{
public static List<Guid> ListOfIds=new List<Guid>();
static GuidHelper()
{
for (int i = 0; i < 10000; i++)
{
ListOfIds.Add(Guid.NewGuid());
}
}
}
public class Grade
{
public Guid StudentId { get; set; }
public string Value { get; set; }
public static IEnumerable<Grade> GetData()
{
for (int i = 0; i < 10000; i++)
{
yield return new Grade
{
StudentId = GuidHelper.ListOfIds[i], Value = "Value " + i
};
}
}
}
public class Student
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Grade { get; set; }
public static IEnumerable<Student> GetStudents()
{
for (int i = 0; i < 10000; i++)
{
yield return new Student
{
Id = GuidHelper.ListOfIds[i],
Name = "Name " + i
};
}
}
}
StudentIdを共通に持つ生徒と成績のリストがメモリ上に存在する。
最初の方法で私は私のマシン上で7秒近くかかるリスト上のLINQを使用して学生の成績を見つけることを試み、別の方法で私は最初にリストを辞書に変換し、1秒未満でかかるキーを使用して辞書から生徒の成績を見つけること。
<イグ
どのように解決するには?
こうすると
student.Grade = grades.Single(x => x.StudentId == student.Id).Value;
このように書くと、全体の
List
を列挙する必要があります (エントリ 0 はラムダと一致しますか? いいえ... エントリー1はラムダに一致しますか?いいえ...等々)。これはO(n)です。すべての生徒に対して一度だけ行うので、O(n^2)になります。
しかし、これを実行すると
student.Grade = dic[student.Id];
ある要素を辞書のキーで探したい場合、それが辞書のどこにあるか瞬時にジャンプすることができます - これは O(1) です。すべての生徒に対して行う場合はO(n)です。(これがどのように行われるかを知りたい場合、Dictionary はキーに対して数学的処理を実行し、それを辞書内の場所 (挿入されたときと同じ場所) である値に変えます)。
つまり、辞書が高速なのは、より優れたアルゴリズムを使用したためです。
関連
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み】WebResource.axdとは何ですか?
-
[解決済み] B "の印刷が "#"の印刷より劇的に遅いのはなぜですか?
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] <は<=より速いのか?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] C#でHashtableよりDictionaryが好まれる理由とは?
-
[解決済み] なぜ[]はlist()よりも速いのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み] [Solved] 不正な文字列値: '\xEFxBFxBD' for column
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み】URLから画像をダウンロードする方法
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?