سؤال

كنت أحاول العثور على أسرع طريقة لحساب عدد العناصر في قائمة تطابق مرشح معين. في هذه الحالة ، العثور على عدد الأرقام الفردية الموجودة في القائمة.

أثناء القيام بذلك ، فوجئت بنتائج مقارنة فهم القائمة مقابل تعبير المولد المكافئ:

python -m timeit -s "L = xrange(1000000)" "sum([1 for i in L if i & 1])"
10 loops, best of 3: 109 msec per loop

python -m timeit -s "L = xrange(1000000)" "sum(1 for i in L if i & 1)"
10 loops, best of 3: 125 msec per loop

لقد حاولت أيضًا أن تكون L قائمة منتظمة ، وأحجام مختلفة ، ولكن في جميع الحالات تفوز فهم القائمة.

ما الذي يفعله GenExp الذي يجعله أبطأ مقارنةً بالقائمة التي تنشئ قائمة جديدة بها مليون عنصر ...؟

(راجع للشغل ، كانت أسرع طريقة وجدتها هي: x = 1; len(filter(x.__and__, L)). ونعم ، أنا أعلم أن كتابة كود مثل هذا يقتل القطط ، أنا أفعل ذلك من أجل المتعة)

هل كانت مفيدة؟

المحلول

عندما تتوفر ذاكرة غير محدودة بشكل أساسي (والتي ستكون دائمًا في المعايير الصغيرة ، على الرغم من أنها في كثير من الأحيان ليست في مشاكل في العالم الحقيقي!-) ، تميل القوائم إلى التفوق على المولدات لأنها يمكن أن يتم تخصيصها مرة واحدة فقط ، في "مجموعة كبيرة" ( لا يوجد تجزئة للذاكرة ، إلخ) ، بينما تتطلب المولدات (داخليًا) جهد إضافي لتجنب نهج "Big Bunch" من خلال الحفاظ على حالة إطار المكدس للسماح باستئناف التنفيذ.

ما إذا كان نهج القائمة أو المولد سيكون أسرع في برنامج حقيقي يعتمد على وضع الذاكرة الدقيق ، بما في ذلك التفتت ، والذي يستحيل التكاثر بدقة في "المرحلة الدقيقة". IOW ، في النهاية ، إذا كنت تهتم حقًا بالأداء ، فيجب أن تقوم بتعيين برامج (ملفات) فعلية (بشكل منفصل) ، وليس فقط "لعبة" العوامل الدقيقة ، في الحالة العامة.

نصائح أخرى

جرب هذا: giveacodicetagpre.

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