C/C++ أفضل طريقة لإرسال عدد وحدات البايت إلى المعياري

StackOverflow https://stackoverflow.com/questions/528559

سؤال

التنميط البرنامج وظيفة الطباعة يأخذ الكثير من الوقت لأداء.كيف يمكنني إرسال "الخام" بايت الإخراج مباشرة إلى المعياري بدلا من استخدام fwrite ، مما يجعلها أسرع (الحاجة إلى إرسال كل 9bytes في المطبوعة() في نفس الوقت المعياري) ?

void print(){
    unsigned char temp[9];

    temp[0] = matrix[0][0];
    temp[1] = matrix[0][1];
    temp[2] = matrix[0][2];
    temp[3] = matrix[1][0];
    temp[4] = matrix[1][1];
    temp[5] = matrix[1][2];
    temp[6] = matrix[2][0];
    temp[7] = matrix[2][1];
    temp[8] = matrix[2][2];

    fwrite(temp,1,9,stdout);

}

مصفوفة ويعرف عالميا أن تكون غير موقعة تشار مصفوفة[3][3];

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

المحلول

IO ليست مكلفة العملية.هو ، في الواقع ، حجب العملية ، وهذا يعني أن نظام التشغيل يمكن استباق العملية الخاصة بك عند الاتصال write لإتاحة المزيد من منضم CPU عمليات تشغيل ، قبل IO الجهاز كنت أكتب اكتمال العملية.

فقط أقل مستوى الوظيفة يمكنك استخدام (إذا كنت النامية على *nix آلة) ، هو استخدام الخام write وظيفة, ولكن حتى ذلك الحين الأداء الخاص بك لن يكون أسرع بكثير مما هو عليه الآن.ببساطة:IO مكلفة.

نصائح أخرى

الجواب الأعلى تصنيفا يدعي أن IO بطيء.

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

كتابة 10 ملايين السجلات من تسعة صفيف بايت

النعناع 12 AMD64 على 3GHz CoreDuo في إطار دول مجلس التعاون الخليجي 4.6.1

   340ms   to /dev/null 
   710ms   to 90MB output file 
 15254ms   to 90MB output file in "dribs" mode 

فري 9 AMD64 على 2.4 GHz CoreDuo تحت رنة 3.0

   450ms   to /dev/null 
   550ms   to 90MB output file on ZFS triple mirror
  1150ms   to 90MB output file on FFS system drive
 22154ms   to 90MB output file in "dribs" mode

لا يوجد شيء بطيء عن IO إذا كنت تستطيع أن المخزن المؤقت بشكل صحيح.

#include <stdio.h> 
#include <assert.h> 
#include <stdlib.h>
#include <string.h>

int main (int argc, char* argv[]) 
{
    int dribs = argc > 1 && 0==strcmp (argv[1], "dribs");
    int err;
    int i; 
    enum { BigBuf = 4*1024*1024 };
    char* outbuf = malloc (BigBuf); 
    assert (outbuf != NULL); 
    err = setvbuf (stdout, outbuf, _IOFBF, BigBuf); // full line buffering 
    assert (err == 0);

    enum { ArraySize = 9 };
    char temp[ArraySize]; 
    enum { Count = 10*1000*1000 }; 

    for (i = 0; i < Count; ++i) {
        fwrite (temp, 1, ArraySize, stdout);    
        if (dribs) fflush (stdout); 
    }
    fflush (stdout);  // seems to be needed after setting own buffer
    fclose (stdout);
    if (outbuf) { free (outbuf); outbuf = NULL; }
}

ووrawest شكل من الناتج يمكنك القيام به هو المحتملة استدعاء النظام write، مثل هذا

write (1, matrix, 9);

1 هو اصف الملف لمعيار من (0 هو المعيار في، و 2 هو الخطأ المعياري). والخروج المعيار الخاص بك فقط الكتابة بالسرعة واحد قراءته في الطرف الآخر (أي محطة أو البرنامج كنت pipeing في) التي قد تكون بطيئة نوعا ما.

وأنا لست متأكدا 100٪، ولكن هل يمكن محاولة وضع عدم عرقلة IO على فد 1 (باستخدام fcntl) ونأمل أن OS العازلة لانها لكم حتى يمكن استهلاكها من قبل الطرف الآخر. انها كانت فترة من الوقت، ولكن اعتقد انه يعمل مثل هذا

fcntl (1, F_SETFL, O_NONBLOCK);

وعلى الرغم من YMMV. يرجى تصحيح لي إذا كنت مخطئا في بناء الجملة، كما قلت، انها كانت فترة من الوقت.

ولعل المشكلة ليست أن fwrite () وبطيئة، ولكن هذا هو مخزنة عليه. حاول الاتصال fflush (المعياري) بعد fwrite ().

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

جميع الطباعة بطيئة إلى حد ما، على الرغم من iostreams بطيئة حقا للطباعة.

وأفضل رهان سيكون لاستخدام printf، شيء على غرار:

printf("%c%c%c%c%c%c%c%c%c\n", matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0],
  matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2]);

ويمكنك ببساطة:

std::cout << temp;

printf هو أكثر C-النمط.

ولكن عمليات IO مكلفة، لذلك استخدامها بحكمة.

كما أن الجميع قد أشار إلى IO في ضيق الحلقة الداخلية مكلفة.لدي عادة انتهى به المشروط cout من مصفوفة على أساس بعض المعايير عند الحاجة لتصحيح ذلك.

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

ما هو الخطأ في:

fwrite(matrix,1,9,stdout);

وعلى حد سواء واحد واثنين من صفائف الأبعاد يستغرق نفس الذاكرة.

حاول تشغيل البرنامج مرتين.مرة واحدة مع الانتاج مرة واحدة دون.ستلاحظ أن وعموما ، فإن واحدة من دون io هو الأسرع.أيضا يمكنك أن شوكة عملية (أو إنشاء موضوع) واحد الكتابة إلى ملف(المعياري) و واحد القيام بعمليات.

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