سؤال

كما أنا حلقة من خلال خطوط في ملف A، أنا أدى تحليل الخط ووضع كل سلسلة (char*) الى char**.

في نهاية السطر، قمت بعد ذلك بتشغيل إجراء يتكون من ملف فتح B، باستخدام fgets, fseek و fgetc للاستيلاء على الشخصيات من هذا الملف. ثم أغلق الملف ب.

أكرر إعادة فتح وإعادة فتح الملف B لكل سطر.

ما أود أن أعرفه هو:

  1. هل هناك أداء كبير يضرب من استخدام malloc و free, ، بحيث يجب أن أستخدم شيئا ثابتا مثل myArray[NUM_STRINGS][MAX_STRING_WIDTH] بدلا من ديناميكي char** myArray?

  2. هل هناك تأثير كبير للأداء من ملف فتح وإغلاق B (من الناحية النظرية، عدة آلاف من المرات)؟ إذا تم فرز الملف الخاص بي، هل هناك طريقة للاستخدام fseek للتحرك "إلى الوراء" في File B، لإعادة تعيين حيث كنت موجودا سابقا في الملف B؟

تعديل اتضح أن اتباع نهج ذو شقين خفضت إلى حد كبير وقت التشغيل:

  1. ملفي B هو في الواقع واحدة من أربعة وعشرين ملفات. بدلا من فتح نفس الملف B1 ألف مرة، ثم B2 ألف مرة، إلخ. أفتح ملف B1 مرة واحدة، أغلقه، B2 مرة واحدة، أغلقه، إلخ. هذا يقلل من الآلاف من الآلاف fopen و fclose العمليات إلى حوالي 24.

  2. انا إستعملت rewind() لإعادة تعيين مؤشر الملفات.

كل هذا أسفر عن تحسن سرعة 60 أضعاف، وهو أكثر من كافية. شكرا لتشير لي إلى rewind().

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

المحلول

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

للسؤال الثاني قرأ عنه rewind. وبعد يجب أن تكون أسرع من فتح وإغلاق طوال الوقت، وتتيح لك القيام بإدارة الموارد أقل.

نصائح أخرى

ما أود أن أعرفه هو:

  • هل يعمل الكود الخاص بك بشكل صحيح؟
  • هل يعمل بسرعة كافية لغرضك؟

إذا كانت الإجابة كل من هذه "نعم"، فلا تغير أي شيء.

يحتوي الافتتاح والإغلاق على مرفقات متغيرة حسب ما إذا كانت البرامج الأخرى منافسة لهذا المورد.

قياس حجم الملف أولا ثم استخدم ذلك لحساب حجم الصفيف مقدما للقيام بتخصيص كومة واحدة كبيرة.

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

لا يمكنك ذاكرة التخزين المؤقت المعلومات الموضعية في الملف الآخر ثم، بدلا من فتح وإغلاقه، استخدم فهارس السابق السابقة كإزاحة؟ يعتمد على المنطق الدقيق حقا.

  1. إذا كانت ملفاتك كبيرة، فستكون القرص I / O أكثر تكلفة بكثير من إدارة الذاكرة. القلق بشأن malloc / الأداء المجاني قبل التنميط يشير إلى أنه من الاختناق هو التحسين المبكر.

  2. من الممكن أن تكون النفقات العامة من Open / Close المتكررة مهمة في برنامجك، ولكن مرة أخرى من المحتمل أن يكون I / O الفعلي أكثر تكلفة، ما لم تكن الملفات صغيرة، وفي هذه الحالة فقدان المخازن المؤقتة بين إغلاق وفتح يمكن تسبب قرص إضافي I / O. ونعم، يمكنك استخدام FTELL () للحصول على الموضع الحالي في ملف ثم FSEEK مع Seek_set للوصول إلى ذلك.

هناك دائما أداء ضرب باستخدام الذاكرة الديناميكية. باستخدام المخزن المؤقت ثابت سيوفر دفعة السرعة.

سيكون هناك أيضا أداء ضرب مع إعادة فتح ملف. يمكنك استخدام FSEEK (POS، Seek_set) لتعيين مؤشر الملفات إلى أي موضع في الملف أو FSEEK (الإزاحة، والسعي_cur) للقيام بحركة نسبية.

ضرب الأداء الهابط هو قريب، وسوف يتعين عليك تحديد ما يعنيه هذا بنفسك.

  1. أعتقد أنه من الأفضل تخصيص المساحة الفعلية التي تحتاجها، وربما لن تكون العلامة العامة مهمة. هذا يتجنب كل من الفضاء الهدر و تفيضات المكدس

  2. نعم. على الرغم من أن IO يتم تخزين مؤقتا، فأنت تجعل Syscalls غير الضرورية (مفتوحة وإغلاقها). استخدام fseek مع ربما SEEK_CUR أو SEEK_SET.

في كلتا الحالتين، هناك بعض ضرب الأداء، لكن الأهمية تعتمد على حجم الملفات والسياق يعمل برنامجك في.

  1. إذا كنت تعرف بالفعل الحد الأقصى لعدد الأوتار وعرض الأقصى، فسيكون ذلك أسرع بكثير (ولكن قد تضيع الكثير من الذاكرة إذا كنت تستخدم أقل من "الحد الأقصى"). الوسيلة السعيدة هي أن تفعل ما هو الكثير من تطبيقات الصفيف الديناميكي في C ++ القيام به: كلما كان لديك Reallec Myarray، Alloc ضعف مساحة ما تحتاجه، و REALLOC فقط مرة أخرى بمجرد نفاد المساحة. هذا يحتوي على تكلفة أداء O (سجل N).

  2. قد يكون هذا أداء كبير. أوصي بشدة باستخدام FSEEK، على الرغم من أن التفاصيل ستعتمد على خوارزمية الخاص بك.

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

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