代码之家  ›  专栏  ›  技术社区  ›  Milan

C/C++最佳方式发送多个字节到STDUT

  •  2
  • Milan  · 技术社区  · 16 年前

    分析我的程序和函数print需要很多时间来执行。如何将“原始”字节输出直接发送到stdout而不是使用fwrite,并使其更快(需要同时将print()中的所有9字节发送到stdout)?

    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];

    9 回复  |  直到 12 年前
        1
  •  10
  •   FreeMemory    16 年前

    IO不是一种廉价的操作。事实上,它是 舞台调度 操作,这意味着当您调用 write 允许更多CPU绑定的进程运行,在您要写入的IO设备完成操作之前。

    您可以使用的唯一较低级别的功能(如果您是在*nix机器上开发的)是使用raw 功能,但即使这样,您的性能也不会比现在快得多。简而言之:IO很贵。

        2
  •  7
  •   Allan Stokes    12 年前

    最受欢迎的答案是IO速度慢。

    这里有一个快速的基准测试,它有足够大的缓冲区,可以将操作系统从关键性能路径中删除,但是 只有 你愿意接受巨大的蓝光输出。如果第一个字节的延迟是您的问题,您需要在“DRIBS”模式下运行。

    从9字节数组中写入1000万条记录

    通用条款第4.6.1款下3GHZ Coreduo上的12 AMD64铸币厂

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

    2.4GHz Coreduo上的FreeBSD 9 AMD64,CLANG 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; }
    }
    
        3
  •  3
  •   Darron    16 年前

    也许您的问题不是fwrite()很慢,而是它被缓冲了。 尝试在fwrite()之后调用fflush(stdout)。

    这完全取决于你对慢的定义。

        4
  •  2
  •   falstro    16 年前

    你能做的最简单的输出形式是 write 像这样的系统调用

    write (1, matrix, 9);
    

    1是标准输出的文件描述符(0是标准输入,2是标准错误)。你的标准输出只能和在另一端(即终端,或者你正在导入的程序)读取它的速度一样快,这可能会相当慢。

    我不是100%确定,但你可以尝试在fd 1上设置非阻塞IO(使用 fcntl )希望操作系统能为您提供缓冲,直到它被另一端消耗掉。已经有一段时间了,但我想它是这样工作的

    fcntl (1, F_SETFL, O_NONBLOCK);
    

    但是YMMV。如果我的语法错误,请纠正我,正如我说的,已经有一段时间了。

        5
  •  1
  •   jasedit    16 年前

    虽然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]);
    
        6
  •  1
  •   vdsf    16 年前

    你可以简单地说:

    std::cout << temp;
    

    普林特 更像C风格。

    然而,IO操作成本很高,所以要明智地使用它们。

        7
  •  1
  •   Ketan    16 年前

    正如大家所指出的,IO在紧密的内环中是昂贵的。通常,当需要调试矩阵时,我会根据一些条件来进行条件查询。

    如果你的应用是控制台应用,那么尝试将其重定向到一个文件,它将比控制台刷新快得多。例如app.exe>matrixdump.txt

        8
  •  0
  •   anon    16 年前

    怎么了:

    fwrite(matrix,1,9,stdout);
    

    一维数组和二维数组占用相同的内存。

        9
  •  0
  •   Daniel    16 年前

    尝试运行程序两次。一次输出,一次不输出。你会注意到,总的来说,没有IO的是最快的。另外,您可以分叉进程(或创建线程),一个写入文件(stdout),另一个执行操作。