سؤال

أنا أكتب برنامجا حيث يكون الأداء مهم للغاية، ولكن ليس حرجا. حاليا أنا أقرأ في النص من FILE* خط حسب الخط واستخدم fgets للحصول على كل سطر. بعد استخدام بعض أدوات الأداء، وجدت أن 20٪ إلى 30٪ من الوقت قيد التشغيل، في الداخل fgets.

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

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

المحلول

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

نصائح أخرى

  1. استخدم fgets_Unlocked ()، ولكن اقرأ بعناية ما يفعله أولا

  2. احصل على البيانات باستخدام FGETC () أو fgetC_Unlocked () بدلا من fgets (). مع FENTS ()، يتم نسخ البيانات الخاصة بك إلى الذاكرة مرتين، أولا بواسطة مكتبة وقت تشغيل C من ملف إلى مخزن مؤقت داخلي (تيار I / O مخزن مؤقتا)، ثم من هذا المخزن المؤقت الداخلي إلى صفيف في البرنامج

قراءة الملف كله في واحد يذهب إلى المخزن المؤقت.

معالجة الخطوط من هذا المخزن المؤقت.

هذا هو أسرع حلا ممكنا.

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

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

اعتمادا على بيئتك، باستخدام Setvbuf () لزيادة حجم المخزن المؤقت الداخلي المستخدمة من خلال تدفقات الملفات قد لا يحسن أو لا تحسن الأداء.

هذا هو بناء الجملة -

setvbuf (InputFile, NULL, _IOFBF, BUFFER_SIZE);

حيث Inputfile هو ملف * إلى ملف مفتوح فقط باستخدام FOPEN () و BUGER_SIZE هو حجم المخزن المؤقت (الذي يتم تخصيصه بواسطة هذه الدعوة لك).

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

إذا كانت البيانات تأتي من القرص، فيمكنك أن تكون ملزمة.

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


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

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

راجع للشغل - قد تكون في العمل أكثر مما يستحق المشكلة؛ ربما آلة أسرع تحل جميع مشاكلك ...

NB - ليس من الواضح أنه يمكنك رسم خريطة الذاكرة المدخلات القياسية إما ...

انظر إلى حمام (). تقرأ أسرع بكثير بالنسبة لي، خاصة إذا تم تعيين المخزن المؤقت للزاحة إلى 65536. السلبيات: عليك أن تفعل الكثير من العمل والكتابة أساسا وظيفة getline الخاصة بك للتحويل من القراءة الثنائية إلى النص. الدفع: ملف I / O

إذا كان نظام التشغيل يدعمه، فيمكنك تجربة قراءة الملف غير المتزامن، أي أن الملف يقرأ في الذاكرة في حين أن وحدة المعالجة المركزية مشغولة بعمل شيء آخر. لذلك، رمز يذهب شيئا مثل:

start asynchronous read
loop:
  wait for asynchronous read to complete
  if end of file goto exit
  start asynchronous read
  do stuff with data read from file
  goto loop
exit:

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

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