11

我想知道从 C 迁移到 shell 脚本的程序的性能会有多糟糕。

我有密集的 I/O 操作。

例如,在 C 语言中,我有一个从文件系统文件读取并写入另一个文件的循环。我在没有任何一致关系的情况下占用每条线的一部分。我正在使用指针来执行此操作。一个非常简单的程序。

在 Shell 脚本中,为了移动一行,我使用${var:(char):(num_bytes)}. 处理完每一行后,我只需将其连接到另一个文件。

"$out" >> "$filename"

该程序执行以下操作:

while read line; do
    out="$out${line:10:16}.${line:45:2}"
    out="$out${line:106:61}"
    out="$out${line:189:3}"
    out="$out${line:215:15}"
    ...
    echo "$out" >> "outFileName"

done < "$fileName"

问题是,C 处理一个 400MB 的文件需要半分钟,而 shell 脚本需要 15 分钟。

我不知道我做错了什么或没有在 shell 脚本中使用正确的运算符。

编辑:我不能使用 awk 因为没有模式来处理该行

我尝试评论“echo $out”>>“$outFileName”,但并没有变得更好。我认为问题在于 ${line:106:61} 操作。有什么建议么?

谢谢你的帮助。

4

3 回答 3

4

根据您的描述,我怀疑您正在 shell 脚本中生成新进程。如果是这样的话,那么这就是你的时间去的地方。分叉/执行一个新进程需要大量操作系统资源。

于 2012-10-26T14:29:24.740 回答
3

正如捐赠者和迪特里希所建议的那样,我对 AWK 语言做了一些研究,而且,正如他们所说,这是完全成功的。这是 AWK 程序的一个小例子:

#!/bin/awk -f
{
    option=substr($0, 5, 9);

    if (option=="SOMETHING"){
        type=substr($0, 80, 1)
        if (type=="A"){
            type="01";
        }else if (type=="B"){
            type="02";
        }else if (type=="C"){
            type="03";
        }

        print substr($0, 7, 3) substr($0, 49, 8) substr($0, 86, 8) type\
        substr($0, 568, 30) >> ARGV[2]

    }
}

它就像一个魅力。处理一个 500mb 的文件只需要 1 分钟

于 2012-11-02T16:33:01.153 回答
2

C程序有什么问题?它坏了吗?维护太难?太不灵活?您更像是壳牌专家而不是 C 专家?

如果它没有坏,就不要修理它。

看看 Perl 也可能是一种选择。比 C 更容易修改,而且 I/O 速度仍然很快;在 Perl 中创建无用的分支比在 shell 中要困难得多。

如果您确切地告诉我们 C 程序的作用,也许在 Unix 工具箱中有一个简单且比光速更快的解决方案,其中包含 sed、grep、awk 或其他 gizmo。换句话说,告诉我们您真正想要实现的目标,不要要求我们解决您在追求您认为朝着实际目标迈出的一步时遇到的一些随机问题。

好的,您的 shell 脚本的一个问题是重复openecho "$out" >> "outFileName". 改用这个:

while read line; do
    echo "${line:10:16}.${line:45:2}${line:106:61}${line:189:3}${line:215:15}..." 
done < "$fileName" > "$outFileName"

作为替代方案,只需使用该cut实用程序(但请注意,它不会在第一部分之后插入点):

cut -c 10-26,45-46,106-166 "$fileName" > "$outFileName"

你明白吗?

于 2012-10-26T15:12:16.810 回答