返回列表 发帖

比较批处理中for、findstr、与sed命令进行文本内容匹配速度测试

【环境】
os:win2k en server
dos窗口:cmd.exe
for命令:系统自带
findstr命令:系统自带
gnu_sed命令:v4.14
super_sed命令:v3.62 (based on gnu_sed v4.1)
【附件】
fi20.bat:for/f命令批处理
fi21.bat:findstr命令批处理
fi22.bat:sed命令批处理
fi23.bat:ssed命令批处理
批处理均使用cadv作为参数执行,即:fi20.bat cadv
cadvfi25.log:批处理调用的数据文件
cadvfi21.csv:批处理调用的数据文件
cadvfi25_t.log:内容与cadvfi25.log基本一致,仅“\”改为“\\”,供findstr,sed调用。
cadvfi23.csv:批处理进行文本匹配生成的数据文件。
cadvfi23.csv_for:与各比较命令批处理相对应的结果数据文件,供检验正确性用。
cadvfi23.csv_findstr:与各比较命令批处理相对应的结果数据文件,供检验正确性用。
cadvfi23.csv_sed:与各比较命令批处理相对应的结果数据文件,供检验正确性用。
cadvfi23.csv_ssed:与各比较命令批处理相对应的结果数据文件,供检验正确性用。
【目的】
比较for命令,findstr命令,与sed命令对文本内容进行匹配的速度,从而择优选用与学习。
【测试方式】
对于相同的内容分别测试上述三个命令进行文本匹配的速度三次,取平均值。
使用for命令的测试批处理:
REM 测试文件匹配的方式与速度
REM Date:[2008-10-11 14:27:52]  Author:nh_wzg
:BEGIN
::File notes...
@echo off
cls&echo.
Title [For command in the match operation]
echo [For command in the match operation]
:INIT
echo [批处理执行初始化(Batch Initializing...)]
echo.
set t=%time%
:MATCH
set /p =[匹配压缩文件与解压文件信息的对应关系并输出 ... <nul
echo md51,fullpath_filename,path,fullname1,fullname2,md52,name2,ext2,size2,ts2,tu,tc,>%1fi23.csv
setlocal enabledelayedexpansion
for /f "skip=2 tokens=2,4 delims= " %%l in (%1fi25.log) do (
    set v1=%%l
    for /f "skip=1 tokens=1-11 delims=," %%a in (%1fi21.csv) do (
        if /i %%l==%%b (
        set aa=%%a
        set bb=%%b
        set cc=%%c
        set dd=%%d
        REM ----------------------------------------------------------------------
        REM findstr /v /c:%%b %1tfi21.csv >t21.csv
        REM move /y t21.csv %1tfi21.csv
        REM ----------------------------------------------------------------------
        )
    )
    echo !aa!,!bb!,!cc!,!dd!,>>%1fi23.csv
    set aa=
    set bb=
    set cc=
    set dd=
)
endlocal
set /p =Done!]<nul
echo.
echo.
echo Command start: %t%
echo Command   end: %time%
echo.
echo.
:END
pause::[Press Any Key to Exit...]&echo.COPY
使用findstr命令的测试批处理:
REM 测试文件匹配的方式与速度
REM Date:[2008-10-11 14:55:39]  Author:nh_wzg
:BEGIN
::File notes...
@echo off
cls&echo.
Title [Findstr command in the match operation]
echo [Findstr command in the match operation]
echo.
:INIT
echo [批处理执行初始化(Batch Initializing...)]
echo.
set t=%time%
:MATCH
set /p =[匹配压缩文件与解压文件信息的对应关系并输出 ... <nul
echo md51,fullpath_filename,path,fullname1,fullname2,md52,name2,ext2,size2,ts2,tu,tc,>%1fi23.csv
setlocal enabledelayedexpansion
for /f "skip=2 tokens=2,4 delims= " %%l in (%1fi25_t.log) do (
    set v1=%%l
    for /f "usebackq tokens=1-11 delims=," %%a in (`findstr /i "%%l" %1fi21.csv`) do (
        set aa=%%a
        set bb=%%b
        set cc=%%c
        set dd=%%d
        REM ----------------------------------------------------------------------
        REM findstr /v /c:%%b %1tfi21.csv >t21.csv
        REM move /y t21.csv %1tfi21.csv
        REM ----------------------------------------------------------------------
    )
    echo !aa!,!bb!,!cc!,!dd!,>>%1fi23.csv
    set aa=
    set bb=
    set cc=
    set dd=
)
endlocal
set /p =Done!]<nul
echo.
echo.
echo Command start: %t%
echo Command   end: %time%
echo.
echo.
:END
pause::[Press Any Key to Exit...]&echo.COPY
使用sed命令的测试批处理:
REM 测试文件匹配的方式与速度
REM Date:[2008-10-11 14:55:39]  Author:nh_wzg
:BEGIN
::File notes...
@echo off
cls&echo.
Title [GNU_sed v4.14 command in the match operation]
echo [GNU_sed v4.14 command in the match operation]
echo.
:INIT
echo [批处理执行初始化(Batch Initializing...)]
echo.
set t=%time%
:MATCH
set /p =[匹配压缩文件与解压文件信息的对应关系并输出 ... <nul
echo md51,fullpath_filename,path,fullname1,fullname2,md52,name2,ext2,size2,ts2,tu,tc,>%1fi23.csv
setlocal enabledelayedexpansion
for /f "skip=2 tokens=2,4 delims= " %%l in (%1fi25_t.log) do (
    set v1=%%l
    for /f "usebackq tokens=1-11 delims=," %%a in (`sed -n "/%%l,/Ip" %1fi21.csv`) do (
        set aa=%%a
        set bb=%%b
        set cc=%%c
        set dd=%%d
        REM ----------------------------------------------------------------------
        REM findstr /v /c:%%b %1tfi21.csv >t21.csv
        REM move /y t21.csv %1tfi21.csv
        REM ----------------------------------------------------------------------
    )
    echo !aa!,!bb!,!cc!,!dd!,>>%1fi23.csv
    set aa=
    set bb=
    set cc=
    set dd=
)
endlocal
set /p =Done!]<nul
echo.
echo.
echo Command start: %t%
echo Command   end: %time%
echo.
echo.
:END
pause::[Press Any Key to Exit...]&echo.COPY
【结果】
在我的机器上面的测试的结果是:findstr(2.95s)》gnu_sed(8.08s)》for /f(8.21s),结果对功能超强的gnu_sed来说,不免会让人失去学习的动力。但是如果对使用sed的批处理稍作修改,使用super_sed v3.62(ssed.exe),结果是惊人的ssed(1.19s)。
可见在一般的情况下面,使用findstr是比较方便的,不仅因为它快,还因为它是随系统自带的。
但sed也值得我们去仔细学习一下,功能太多了,但是为了速度,也许我们要对它的版本作个选择。

[ 本帖最后由 nh_wzg 于 2008-10-11 17:53 编辑 ]

测试样本太小了
最好找IDA生成的文件做测试才更有说服力。

TOP

学习了。。。谢谢楼主及各位大大

TOP

各位老大都给了深入的指点,在下受教学习了。
谢谢!!

TOP

呵呵,又是效率的话题。!
我说两句。。
首先,我不同意楼主的说的 sed 效率低下。
楼主的测试代码只能说是在批处理中频繁调用外部命令会使批处理运行效率低。而不是命令本身效率低。
关于此话题在我的另一帖中曾讨论过
http://bbs.bathome.net/thread-2089-1-1.html

如果楼主想证实的是这三个命令“匹配文本的速度”那么你的代码不能说明什么。
而应该是用以下的方式测试。

以大小为 2.22m 的a.txt文件为测试样本。
以下三句代码都是匹配 a.txt 中以 ok 开头的行,速度都是快的惊人!
for /f "delims= " %%a in (a.txt) do if "%%a"=="ok" echo %%a
findstr "^ok" a.txt
sed -n "/^ok/p" a.txt
pauseCOPY
但功能却各有不同,
for 虽说速度也快,但受特殊字符的限制,且若是需要对每行都进行处理时速度是不及sed之万一的。
findstr 可以匹配指定的行,但无法对其进行处理,且匹配的局限性很大。
而sed 是有名的文本流编辑器,以功能强大和高效著称。可以匹配各种自定义条件的行并对其进行处理。
5楼说的好, 用最合适的代码做最合适的事。

楼主不防试试分别用 for 和 sed 给文档每行开头都加一个字符串,看看谁更快?
或是替换每行的指定字符串?
或是给文档的第某行至某行的字符串进行替换?

sed 效率并不慢,只是楼主的使用方法不当而以。。(仅对顶楼测试代码而言)

[ 本帖最后由 随风 于 2008-10-12 01:50 编辑 ]
技术问题请到论坛发帖求助!

TOP

我们可以拿拳头去打蚊子,也可以用蚊香去薰蚊子。
但我们不能因为前者的灭蚊效果比不上后者,就说拳头不如蚊香好。
sed亦然。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

原帖由 pusofalse 于 2008-10-11 18:41 发表
@echo off
echo %time%
sed -e "/d:\\dos\\temp\\I386\\0[0-9A-Z]\{3\}/!d" -e "s/^,//" -e "s/\(CS_,\)[0-9A-Z]\{4\}.*/\1/" "cadvfi21.csv">test
start notepad.exe test
echo %time%
pause初学sed,很繁杂, ...


因为原来的测试中要由一个LOG文件提取文件名数据,再根据提取的文件名取得相关数据,再合成一个相互对应的数据文件,以我现在的水平,只能够使用FOR+SED/FINDSTR来实现。

另外就是想提供一个我环境下面的数据,我认为在例子的环境下面,大家的条件是基本一样的,仅测这一匹配操作的速度来比较。

TOP

原帖由 yslyxqysl 于 2008-10-11 18:28 发表
请将3个附件发在同一帖内或三个文件压成一个rar文件。

因为还不熟悉论坛,不知道一个帖子内可以上传几个接近100k的附件。试看是否能够改正。

TOP

@echo off
echo %time%
sed -e "/d:\\dos\\temp\\I386\\0[0-9A-Z]\{3\}/!d" -e "s/^,//" -e "s/\(CS_,\)[0-9A-Z]\{4\}.*/\1/" "cadvfi21.csv">test
start notepad.exe test
echo %time%
pauseCOPY
初学sed,很繁杂,但测试用时能控制在0.5s之内。
心绪平和,眼藏静谧。

TOP

回复 3楼 的帖子

请将3个附件发在同一帖内或三个文件压成一个rar文件。

TOP

总觉得sed的效率如此低下有点不可思议,应该是配合了for在使用。
只用sed的正则表达式,完全可以匹配出想要的内容。
心绪平和,眼藏静谧。

TOP

不好意思,因为这个比较是从我的一个测试中临时抽出来的,原贴没有对批处理的参数加以颜色,大小强调,要加一个“cadv”参数在每个批处理的后面。

TOP

用最合适的代码做最合适的事情吧。
另,同遇到6楼的问题。
心绪平和,眼藏静谧。

TOP

[匹配压缩文件与解压文件信息的对应关系并输出 ... 系统找不到文件 fi25.log。
Done!]
什么意思?

TOP

颇强大,试下先

TOP

返回列表