سؤال

أكتب وظيفة PHP التي ستحتاج إلى حلقة فوق مجموعة من المؤشرات ولكل عنصر، وسحب في تلك البيانات (سواء كانت من قاعدة بيانات MySQL أو ملف مسطح). هل سيكون لدى أي شخص أي أفكار لتحسين ذلك حيث يمكن أن يكون هناك الآلاف والآلاف من التكرارات؟

كانت فكرتي الأولى هي الحصول على مجموعة ثابتة من البيانات المخزنة مؤقتا والتي أعمل عليها وأي تعديلات ستغير فقط الصفيف المخزن مؤقتا ثم في النهاية يمكنني مسحها على القرص. ولكن في حلقة من أكثر من 1000 عنصر، سيكون هذا عديمة الفائدة إذا كنت فقط تبقي حوالي 30 في الصفيف. كل عنصر ليس كبيرا جدا ولكن 1000+ منها في الذاكرة أكثر من اللازم، وبالتالي الحاجة إلى تخزين القرص.

البيانات هي مجرد كائنات متسلسلة. حاليا أستخدم قاعدة بيانات لتخزين البيانات، لكنني أفكر ربما تكون الملفات المسطحة ستكون أسرع (لا أهتم بقضايا التزامن ولا أحتاج إلى تحليلها، فقط Unzip and Unerialize). لدي بالفعل جهاز كمتدرج مخصص سيسحب في 5 عناصر في وقت واحد (لخفض اتصالات DB) وتخزينها في ذاكرة التخزين المؤقت هذه. ولكن مرة أخرى، باستخدام ذاكرة التخزين المؤقت 30 عندما أحتاج إلى التكرار من الآلاف عديمة الفائدة إلى حد ما.

أساسا أنا فقط بحاجة إلى طريقة للتكرار على هذه العناصر العديدة بسرعة.

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

المحلول

حسنا، لم تمنح الكثير للذهاب. أنت لا تصف بياناتك، ولا تصف ما تفعله بياناتك أو عندما تحتاج إلى كائن واحد بدلا من آخر، وكيف يتم إصدار هذه الكائنات مؤقتا، وتحت أي ظروف تحتاج إليها، و .. وبعد

لذلك أي شخص يقول أي شخص هنا سوف يكون طلقة كاملة في الظلام.

... حتى على طول تلك الخطوط، إليك تسديدة في الظلام.

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

وهذا ما يسمى LRU. algroithm. إنها مخطط بديل الصفحات للذاكرة الافتراضية. ما هو عليه هو تأخير عنق الزجاجة (القرص I / O) حتى من المستحيل تجنبه. تجدر الإشارة إلى أن هذه الخوارزمية لا تضمن البديل الأمثل، لكنها تؤدي بشكل جيد.

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

<تحرير> استنادا إلى تعليقك، أنت تعمل على شبكة عصبية. في حالة حثك الأولي للبيانات (قبل مرحلة التصحيح)، أو عند استخدامه بنشاط للتصنيف، لا أرى كيف تكون الخوارزمية فكرة سيئة، إلا إذا لم يكن هناك طريقة ممكنة فقط لتناسب العقد الأكثر استخداما في الذاكرة.

في مرحلة التصحيح (ربما ظهر الدعامة؟)، يجب أن يكون واضحا ما العقد يجب أن تبقي في الذاكرة ... لأنك قمت بالفعل بزيارةهم!

إذا كانت شبكتك كبيرة، فلن تبتعد مع عدم وجود قرص I / O. الحيلة هي إيجاد طريقة لتقليلها. </ edit>

نصائح أخرى

من الواضح أن الحفاظ عليه في الذاكرة أسرع من أي شيء آخر. ما حجم كل عنصر؟ حتى لو كانت 1K كل، عشرة آلاف منهم فقط 10 م.

يمكنك دائما الخروج عن حلقة بعد الحصول على البيانات التي تحتاج إليها. بحيث لن يستمر في حلقات. إذا كان ذلك ملفا مسطحا، فأنت تخزن .. سيعاني الخادم HDD يحتوي على آلاف أو ملايين الملفات بحجم ملف مختلف. ولكن إذا كنت تتحدث عن الملف الفعلي بأكمله المخزنة في DB. ثم من الأفضل تخزينها في مجلد فقط وحفظ مسار هذا الملف في DB. وحاول وضع العناصر المسحوبة في XML. بحيث يكون من الأسهل الوصول إليه ويمكن أن يحتوي على العديد من السمات لتفاصيل العنصر الذي تم سحبه على سبيل المثال (الاسم أو تاريخ تحميله وما إلى ذلك).

يمكنك استخدام memcached لتخزين الكائنات في المرة الأولى التي يقرأ فيها، ثم استخدم الإصدار المخزن مؤقتا في المكالمات اللاحقة. استخدام Memcached RAM لتخزين الكائنات حتى يكون لديك ذاكرة كافية، سيكون لديك استلقاء كبير. هناك API php إلى memcached

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