bash、perl处理文件效率对比

场景:按照对应关系(对应关系存在一个文件中)每行读取替换文件中的指定字段,10万行

例如对应关系存在pairs.txt中:

ABABAB|CDCDCDCD

ACACAC|CACACACA

BBBBBB|CCCCCCCC

AAAAAA|BBBBBBBB

CCCCCC|DDDDDDDD

需要替换的文件contents.txt,需要替换第4个字段:

1|2|3|ABABAB|4

1|2|3|ACACAC|4

1|2|3|BBBBBB|4

1|2|3|ABABAB|4

1|2|3|AAAAAA|4

1|2|3|ABABAB|5

......

......{省略剩下的10W行+}

由于比较熟悉bash,第一反应是写个bash脚本处理:

#!/bin/bash

rm newfile.txt

#存放替换的键值对

declare -A keywords

keyfile=$1

transfile=$2

count=$3

if [ ! $# -eq 3 ]

then

    echo "need 3 args"

    exit -1

fi

while read line

do

    if [ ! "$line" = "" ]

    then

        keyval=(${line//|/ })

        key=${keyval[0]}

        val=${keyval[1]}

        keywords[$key]=$val

    fi

done < $keyfile

mapfile myarr < $transfile

for line in ${myarr[@]}; do

    numbers=(${line//|/ })

    number=${numbers[$count]}

    tmpkeyval="${keywords[$number]}"

    if [ ! "$tmpkeyval" = "" ]

    then

        numbers[$count]=$tmpkeyval

        newline=""

        for var1 in ${numbers[@]}

        do

          if [ "${newline}" = "" ];then

              newline=$var1

          else

              newline="${newline}|$var1"

          fi

        done

        echo "$newline" >> newfile.txt

    fi

done

统计一下执行时间,执行时间较长,38秒多:

[xxxx]$  time ./cuttingx.sh pairs.txt contents.txt 3

real    0m38.619s

user    0m34.861s

sys    0m3.705s

由于实际业务中要处理的文件是200W行以上,按照上述实验的估算,执行耗时不可接受。

同事说perl实现很快,学了一下基本语法,开干

#!/usr/bin/perl

if(@ARGV != 4){

    print "need 3 args";

    exit 1;

}

$transfile = shift @ARGV;

$srcfile = shift @ARGV;

$index = shift @ARGV;

$outfile = shift @ARGV;

%hashs;

open(DATA, "<$transfile") or die "can not open file $transfile: $!";

while(<DATA>){

    chomp;

    @keys = split /\|/;

    $hashs{$keys[0]} = $keys[1];

}

close $transfile;

open(SRCDATA, "<$srcfile") or die "can not open file $srcfile: $!";

open(OUTFILE, ">>$outfile") or die "can not open file $outfile: $!";

while(<SRCDATA>) {

    chomp;

    @values = split /\|/;

    $tmp = $values[$index];

    if(exists $hashs{$tmp}) {

        $values[$index] = $hashs{$tmp};

    }

    $newline = '';

    $newline = join('|',@values);

    print OUTFILE "$newline\n";

}

close $srcfile;

close $outfile;

统计一下执行时间,执行时间缩短了很多,和bash相比提升了n个级别

[xxxx]$ time ./trans.pl pairs.txt contents.txt 3 output.txt

real    0m0.574s

user    0m0.564s

sys    0m0.009s


最后用c++实现一遍,做个对比:

#include <iostream>

#include <map>

#include <string.h>

#include <stdio.h>

void split(char *src,const char *separator,char **dest,int *num);

using namespace std;

int main(int argc, char* args[]) {

    FILE * keysfile = fopen(args[1], "r");

    FILE * contents = fopen(args[2], "r");

    FILE * outputfile = fopen(args[3], "rw+");

    char readbuf[1024];

    map<string, string> keys;

    char *p[2] = {0};

    char *p1[10] = {0};

    int num = 0;

    while(fgets(readbuf, 1024, keysfile)) {

        split(readbuf, "|", p, &num);

        keys.insert(pair<string, string>(p[0], p[1]));

    }

    while(fgets(readbuf, 1024, contents)) {

        split(readbuf, "|", p1, &num);

        string tmp = p1[3];

        string outline = "";

        if(keys.find(tmp) != keys.end()) {

            //p1[3] = keys[tmp].c_str();

            //printf("exsit:%s\n", keys[tmp].c_str());

            for(int i = 0;i < num;i++) {

                if(i == 0) {

                    outline = p1[0];

                }

                else if(i == 3) {

                    outline = outline + "|" + keys[tmp];

                }else{

                    outline = outline + "|" + p1[i];

                }

            }

            fputs(outline.c_str(), outputfile);

        }else{

            fputs(readbuf, outputfile);

        }

    }

    fclose(keysfile);

    fclose(contents);

    fclose(outputfile);

    return 0;

}

void split(char *src,const char *separator,char **dest,int *num) {

    char *pNext;

    int count = 0;

    if (src == NULL || strlen(src) == 0)

        return;

    if (separator == NULL || strlen(separator) == 0)

        return;

    char *strtok(char *str, const char *delim);

    pNext = strtok(src,separator);

    while(pNext != NULL) {

        *dest++ = pNext;

        ++count;

        pNext = strtok(NULL,separator);

    }

    *num = count;

}

[xxx]# time ./cut pairs.txt contents.txt out.txt

real    0m0.325s

user    0m0.322s

sys    0m0.002s

原理:

Perl是一种类似basic的脚本语言。专业化一点来说,Perl是一种字节编译语言,并且还是一个字节解释器。它不会象unix中的shell读程序一样,对程序进行逐行执行。相反,Perl会先通读一遍文件,将其编译为内部表达式,然后执行指令。

虽然Perl是一种脚本语言,但是在所有的脚本语言中,它的执行速度可能是最快的。因为Perl本身是采用C语言开发,很多模块也是使用C语言开发的。换句话说,Perl执行某项指令可能是直接调用C语言开发的函数。

在编译的同时,也进行了一些代码的优化,例如,消除了不可能执行的代码,计算了常量表达式,加载了库定义。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容