2013-02-06 29 views
0

我试图将一个持续的数据流(非常大)保存到二进制文件中。 该数据流是与使用管道,scanf写入float流时速度低

find . -name "(pattern)" | xargs -L1 awk '{(smth)}' | ./translater 

产生的“转换器”是一个Ç代码恢复从所述第二管道中的数据流。

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

int main() { 
    float buffer; 
    FILE *stream; 

    stream = fopen("output.bin", "wb"); 
    while (scanf("%f", &buffer)==1) { 
     fwrite(&buffer, 1, sizeof(float), stream); 
    } 
    fclose(stream); 
    return (0); 
} 

这些组合运行良好,但花费很长时间(> 3小时)生成2GB二进制文件。有什么我可以改进,以加速它?

+1

尝试阅读和书写更大的块。 – 2013-02-06 20:03:28

+0

你确定这是C程序慢的部分吗?您正在为每个输入文件重新执行'awk'。有多少个输入文件?如果你举一个'pattern'和'{(smth)}'的例子,那么人们会更容易帮助你回答你的问题。 – andrewdotn

+0

管道内核缓冲区很小。很可能大部分时间都花在上下文切换上。你可能想要分析它。一个简单的测试就是将输出保存到文件中,然后将文件送入下一个阶段而不是使用shell管道。 –

回答

0

您正在执行awk将近4,000,000次。在我的机器上,执行awk需要大约5秒钟,即使awk什么也不做。您可以在shell的时候这样说:

time for ((i = 0; i < 1000; i++)); do gawk 1 < /dev/null; done 

这意味着awk初始化您的问题独处的时间需时约4000 * 5/60/60 = 5.5小时,甚至没有做任何工作。

尝试

find . -name "(pattern)" | xargs cat | awk '{print $2}' | ./translater 

只执行一个awk过程。

如果仍然很慢,请尝试对时间线的每个部分进行单独计时 - 运行多长时间需要findcat/dev/null需要多长时间?运行多长时间awk

fwrite通常会被缓冲,因此您的翻译程序不应该成为问题。

+0

谢谢安德鲁。我在awk语句中有一个'if(NR <= 141)'(每个文件600行)。我试过在awk中删除'if()',程序运行速度非常快。现在,我认为这是'如果'减缓了日常工作。 – Kai

+0

我更新它:'find。 -name“(pattern)”| xargs看到-n'1,141p'| awk'{print $ 2}'| 。/ translater“效果更好。 – Kai