سؤال

أكثر من حوالي ينق [إدراج المفضلة لديك موفر هنا], هذا السؤال هو حول البحث أو التصفية في الذاكرة مجموعات.

أنا أعرف ينق (أو البحث/تصفية أساليب الإرشاد) يعمل في الكائنات تنفيذ IEnumerable أو IEnumerable<T>.السؤال هو: لأن من طبيعة تعداد كل استعلام التعقيد على الأقل O(n)?

على سبيل المثال:

var result = list.FirstOrDefault(o => o.something > n);

في هذه الحالة, كل خوارزمية سوف يستغرق على الأقل O(n) إلا إذا list هو أمر يتعلق 'something', في هذه الحالة فإن البحث يجب أن تأخذ O(log(n)):ينبغي أن يكون البحث الثنائية.ومع ذلك ، إذا فهمت بشكل صحيح, هذا الاستعلام سيتم حلها من خلال التعداد ، لذلك يجب أن تأخذ O(n), حتى في list كان أمر في وقت سابق.

  • هل هناك شيء يمكنني القيام به من أجل حل استعلام في O(log(n))?
  • إذا كنت تريد الأداء ، يجب استخدام صفيف.نوع الصفيف.BinarySearch?
هل كانت مفيدة؟

المحلول

حتى مع parallelisation, انها لا تزال O(n).عامل ثابت ستكون مختلفة (اعتمادا على عدد من النوى) ولكن كما n متنوعة إجمالي الوقت سوف لا تزال تختلف خطيا.

بالطبع, يمكنك أن تكتب الخاصة بك تطبيقات مختلفة LINQ المشغلين على البيانات الخاصة بك أنواع ، لكنها فقط تكون مناسبة في حالات محددة جدا - عليك أن تعرف بالتأكيد أن المسند فقط تعمل على تحسين جوانب البيانات.على سبيل المثال, إذا كنت قد حصلت على قائمة من الناس أن هذا أمر من العمر, انها لن تساعدك مع استعلام الذي يحاول العثور على شخص ما مع اسم معين :)

دراسة المسند عليك استخدام التعبير الأشجار بدلا من المندوبين ، و أن الحياة أصبحت أصعب بكثير.

وأظن أنني عادة إضافة أساليب جديدة والتي تجعل من الواضح أن كنت تستخدم فهرسة/أمر/ما طبيعة نوع البيانات التي سوف تعمل دائما بشكل مناسب.لا يمكنك بسهولة الاحتجاج بتلك أساليب إضافية من تعبيرات الاستعلام, بالطبع, ولكن لا يزال بإمكانك استخدام LINQ مع تدوين نقطة.

نصائح أخرى

نعم, عام القضية هي دائما O(n) ، Sklivvz قال.

إلا أن العديد من وسائل LINQ حالة خاصة عند الكائن تنفيذ IEnumerable في الواقع تنفذ مثلICollection.(لقد رأيت هذا IEnumerable.يحتوي على الأقل.)

في الواقع هذا يعني أن ينق IEnumerable.يحتوي على المكالمات بسرعة HashSet.يحتوي على سبيل المثال إذا كان IEnumerable هو في الواقع HashSet.

IEnumerable<int> mySet = new HashSet<int>();

// calls the fast HashSet.Contains because HashSet implements ICollection.
if (mySet.Contains(10)) { /* code */ }

يمكنك استخدام عاكس للتحقق بالضبط كيف LINQ أساليب محددة ، وهذا هو كيف استنتجت هذا

كما ينق يحتوي على أساليب IEnumerable.ToDictionary (خرائط المفتاح إلى قيمة واحدة) و IEnumerable.ToLookup (خرائط مفتاح قيم متعددة).هذا القاموس/جدول بحث يمكن إنشاء مرة واحدة واستخدامها مرات عديدة ، والتي يمكن أن تصل سرعة بعض LINQ كثيفة رمز من حيث الحجم.

نعم, يجب أن يكون ، لأن الطريقة الوحيدة للوصول إلى أي عضو IEnumerable باستخدام أساليب ، مما يعني O(n).

يبدو أن حالة كلاسيكية في اللغة المصممين قررت التجارة أداء عمومية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top