سؤال

لقد أُبلغت أن مكتبتي أبطأ مما ينبغي ، بترتيب أكثر من 30 مرة بطيئة للغاية في تحليل ملف معين (ملف نصي ، حجم 326 كيلو بايت). اقترح المستخدم أنه قد أستخدمه std::ifstream (من المفترض بدلاً من FILE).

أفضل عدم إعادة الكتابة بشكل أعمى ، لذلك اعتقدت أنني سأتحقق هنا أولاً ، لأن تخميني سيكون عنق الزجاجة في مكان آخر. أنا أقرأ الحرف ، لذا فإن الوظائف الوحيدة التي أستخدمها get(), peek(), ، و tellg()/seekg().

تحديث:

لقد حددت ، وحصلت مربك الإخراج - لا يبدو أن GPROF يعتقد أن الأمر استغرق وقتًا طويلاً. أعيد كتابة البرنامج لقراءة الملف بأكمله في المخزن المؤقت أولاً ، وقد انطلق بحوالي 100x. أعتقد أن المشكلة ربما كانت tellg()/seekg() استغرق ذلك وقتًا طويلاً ، ولكن ربما لم يتمكن GPROF من رؤية ذلك لسبب ما. على كل حال، ifstream يفعل ليس يبدو أنه يخزن الملف بأكمله ، حتى لهذا الحجم.

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

المحلول

لا أعتقد أن هذا سيحدث فرقًا. خاصة إذا كنت تقرأ char بواسطة char ، فمن المحتمل أن تهيمن الإدخال/الإخراج بشكل كامل اى شئ آخر. لماذا تقرأ بايت واحد في كل مرة؟ أنت تعرف كم هو غير فعال للغاية؟

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

الفرق بين std :: ifstream ومكافئ C ، هو في الأساس استدعاء وظيفة افتراضية أو اثنتين. قد يحدث فرق إذا تم تنفيذه بضع عشرات من مليون مرة في الثانية ، وإلا ، وليس حقيقي. ملف I/O بشكل عام بطيء جدًا لدرجة أن واجهة برمجة التطبيقات التي تستخدم للوصول إليها لا تهم حقًا. ما يهم أكثر بكثير هو نمط القراءة/الكتابة. الكثير من السعيات سيئة ، قراءات متتابعة/تكتب جيدة.

نصائح أخرى

يجب أن يكون أبطأ قليلاً ، ولكن مثل ما قلته ، قد لا يكون عنق الزجاجة. لماذا لا تقوم بتشكيل البرنامج الخاص بك ومعرفة ما إذا كان هذا هو الحال؟

أعتقد أنه من غير المرجح أن يتم إصلاح مشكلتك عن طريق التبديل من FStream إلى ملف*، وعادة ما يتم تخزينها بواسطة مكتبة C. كما يمكن أن يقرأ نظام التشغيل ذاكرة التخزين المؤقت (Linux جيد جدًا في هذا الجانب). بالنظر إلى حجم الملف الذي تصل إليه ، فمن المحتمل أن يكون بالكامل في ذاكرة الوصول العشوائي.

مثل PolyThinker ، يقول أفضل رهان لك هو تشغيل برنامجك ، وهو محدد تحديد مكان المشكلة.

كما أنك تستخدم Seekg/Tellg هذا يمكن أن يسبب تأخيرات ملحوظة إذا كان القرص الخاص بك مجزأًا بشدة ، لأنه لقراءة الملف لأول مرة ، يتعين على القرص نقل الرؤوس إلى الموضع الصحيح.

كل المعايير شريرة. فقط ملف تعريف رمزك للبيانات التي تتوقعها.

لقد أجريت مقارنة أداء I/O بين Ruby و Python و Perl و C ++ مرة واحدة. بالنسبة لبيبيات ، كانت إصدارات اللغات ، وما إلى ذلك ، أن المتغير الذي يتجه إليه C ++ أبطأ عدة مرات (كان مفاجأة كبيرة في ذلك الوقت).

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

هنا هو معيار ممتاز يوضح أنه في ظل الظروف القاسية ، fstreamS في الواقع بطيئة جدا ... ما لم:

  1. يمكنك استخدام التخزين المؤقت (لا يمكنني التأكيد على ذلك بما فيه الكفاية)
  2. أنت تتلاعب بالمخزن المؤقت بنفسك (أي إذا كنت بحاجة إلى أداء مثل OP في السؤال المرتبط) ، وهو ما لا يختلف عن استخدامه FILE*.

يجب ألا تحسن قبل الأوان. fstreams عمومًا أفضل ، وإذا كنت بحاجة إلى تحسينها في الطريق ، فيمكنك دائمًا القيام بذلك لاحقًا بتكلفة قليلة. من أجل الاستعداد للأسوأ مسبقًا ، أقترح إنشاء الحد الأدنى من الوكيل لـ fstream الآن حتى تتمكن من تحسينه لاحقًا ، دون الحاجة إلى لمس أي شيء آخر.

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