谢谢你的回答。看起来你很好。
原因是正在搜索引用的标签
首先在批处理文件中向下,然后从顶部到文件底部都找不到它。
我验证了使用第一个批处理文件时,文件大小为941字节,行数如下:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "StartTime=%%I"
for /F "usebackq delims=" %%I in ("%TEMP%\HexValues.dat") do call :ConvertLine "%%I"
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "EndTime=%%I"
set /A StartTime=(1%StartTime:~8,2% - 100) * 3600 + (1%StartTime:~10,2% - 100) * 60 + 1%StartTime:~12,2% - 100
set /A EndTime=(1%EndTime:~8,2% - 100) * 3600 + (1%EndTime:~10,2% - 100) * 60 + 1%EndTime:~12,2% - 100
set /A DiffTime=EndTime - StartTime
echo Time: %DiffTime% seconds
endlocal
goto :EOF
:ConvertLine
set "DataLine=%~1"
set "AllValues="
set "StartColumn=0"
:NextValue
set /A Value=0x!DataLine:~%StartColumn%,4!
set "AllValues=%AllValues%,%Value%"
set /A StartColumn+=4
if not %StartColumn% == 32 goto NextValue
goto :EOF
花了
34
51
Windows XP笔记本电脑上的秒数。
goto :EOF
和
:ConvertLine
包含250行且所有行都具有相同字符串的块:
rem comment line of no interest
此批处理文件需要9193字节
64
秒完成完全相同的任务。
主要地
因为同样的原因。
但我仍然没有找到为什么第二批处理文件需要9193字节
72
秒而不是
笔记本电脑上的秒数使用电池而不是插入电源。批处理文件和数据文件加载到缓存中。运行批处理文件时没有输出。我在电源选项中配置了在电池上运行时使用最高性能。在批处理文件中扫描标签在电池上运行时明显比在插入电源上运行时慢,尽管在批处理文件执行期间并没有真正访问硬盘,只有CPU核心、CPU缓存和RAM。
TIME
环境变量,而不是使用
WMIC
%TIME%
在我的电脑上扩展为德语时间格式
HH::MM:SS.ms
.
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "StartTime=%TIME%"
for /F "usebackq delims=" %%I in ("%TEMP%\HexValues.dat") do call :ConvertLine "%%I"
set "EndTime=%TIME%"
set /A StartTime=(1%StartTime:~0,2% - 100) * 3600 + (1%StartTime:~3,2% - 100) * 60 + 1%StartTime:~6,2% - 100
set /A EndTime=(1%EndTime:~0,2% - 100) * 3600 + (1%EndTime:~3,2% - 100) * 60 + 1%EndTime:~6,2% - 100
set /A DiffTime=EndTime - StartTime
echo Time: %DiffTime%
endlocal
goto :EOF
:ConvertLine
set "DataLine=%~1"
set "AllValues="
set "StartColumn=0"
:NextValue
set /A Value=0x!DataLine:~%StartColumn%,4!
set "AllValues=%AllValues%,%Value%"
set /A StartColumn+=4
if not %StartColumn% == 32 goto NextValue
goto :EOF
此批处理文件在中完成
30
在Windows XP x86(硬盘驱动器为ST980411ASG,转速为7200 rpm)上插入电源后运行秒。下一个在电池上运行的批处理文件
37
花了
72
使用Windows 7 x64和三星SSD 850 EVO(固态磁盘)并插入电源和
77
在电池上运行的秒数。我刚刚在两次测试之间切断了电源,没有其他变化。没有连接到任何网络,每个硬件交换机关闭WLAN,BIOS中禁用蓝牙,执行期间禁用防病毒应用程序(Windows 7x 64上的Windows Defender除外)。
我用Windows7x64在PC上一次又一次地运行这个批处理文件,最后在执行过程中经常打开风扇,执行时间随着时间的推移变得恒定
秒独立于电源是否插入。
为了进行比较,我还执行了这个批处理文件:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "StartTime=%TIME%"
for /F "usebackq delims=" %%I in ("%TEMP%\HexValues.dat") do (
set "DataLine=%%I"
set "AllValues="
for /L %%J in (0,4,28) do (
set /A Value=0x!DataLine:~%%J,4!
set "AllValues=!AllValues!,!Value!"
)
)
set "EndTime=%TIME%"
set /A StartTime=(1%StartTime:~0,2% - 100) * 3600 + (1%StartTime:~3,2% - 100) * 60 + 1%StartTime:~6,2% - 100
set /A EndTime=(1%EndTime:~0,2% - 100) * 3600 + (1%EndTime:~3,2% - 100) * 60 + 1%EndTime:~6,2% - 100
set /A DiffTime=EndTime - StartTime
echo Time: %DiffTime%
endlocal
在运行Windows XP的电脑上,需要1到2秒的时间才能完成,因此,在插入电源的情况下,完成时间通常为1秒,而在使用电池的情况下,完成时间通常为2秒。我还需要考虑毫秒,以便更精确地处理这个快速完成的解决方案。在PC Windows 7 x64上的执行时间在4到5秒之间,与其他Windows XP笔记本电脑一样,插入电源的时间也有缩短的趋势。
但我可以用你的眼睛看
Process Monitor
后藤
使用最优化的版本,在几乎没有批处理文件访问的情况下进行循环
对于
环
及
cmd.exe
真正地一行一行地读取批处理文件
后藤
方法,因为它也可以看到与过程监控对大量的
ReadFile
访问量与日俱增
Offset
偏移量与批处理文件中每行开头的偏移量相同。Process Monitor记录文件系统访问时,由于记录的事件超过两百万个,显示的事件超过500000个,因此执行时间显著增加。
对于
循环那个
命令提示符
读到最后一行
循环,然后读取一次
HexValues.dat
只有一个
access,需要5秒钟(在Windows 7 x64上)完成从十六进制到十进制的转换,而无需任何文件系统访问,然后读取批处理文件的其余行以完成其执行。Process Monitor只记录大约50000个事件,显示的事件不到100个。
后藤
结论:
这个
后藤
方法1的求解速度比所有其他方法慢得多,因为
goto NextValue
根据
Aacini
-
打开批处理文件以读取和查询有关文件的标准信息,以检查自上次访问以来批处理文件是否已更改。在下面的其他步骤中,不会查询标准信息。
-
从批处理文件中一行接一行地读取,并处理每一行,以查找具有
:NextValue
没有成功结束文件。
-
-
从批处理文件的最上面一行接一行地读取,然后处理每一行以查找具有
:下一个值
.
-
:下一个值
-
-
set /A Value=0x!DataLine:~%StartColumn%,4!
.
-
-
处理读取命令行。
-
-
读下一行
set "AllValues=%AllValues%,%Value%"
从批处理文件。
-
-
处理读取命令行。
-
再次打开批处理文件。
-
读下一行
set /A StartColumn+=4
-
关闭批处理文件。
-
处理读取命令行。
-
-
if not %StartColumn% == 32 goto NextValue
从批处理文件。
-
关闭批处理文件。
-
处理读取命令行。
-
如果条件为真,则继续执行第一步,即。
StartColumn
不是
32
.
所有这些批处理文件
即使不访问存储介质,操作也需要几毫秒,但是
很可能
(我的假设)在访问主板上的DRAM时,由于整个批处理文件内容没有加载到CPU的内部缓存中,所以在主板上加载了文件。
因此,使用
对于
通过方法2在子例程中循环批处理文件访问操作的数量已经大大减少,因为在处理从中读取的当前行中的十六进制值时,不需要执行21个步骤(具有更多文件访问操作)逐行读取批处理文件,也不需要显式列出所有单个步骤
.
所有的线都在里面
HexValues.dat
可以由
命令提示符
在一次完成整个转换时不访问批处理文件
按照方法3和4进行循环。最后,通过将CSV的所有行输出到,可以保存更多的文件系统访问
STDOUT
(内存中的缓冲区)并将其写入CSV文件一次,如方法4所做,与方法3相比,再次减少此值转换任务所需的总时间。
应该避免在命令行中使用
goto LABEL
或
call :LABEL
具有
LABEL
在一个更大的批处理文件中,位于当前行的上方或下方的许多行,在一个循环中进行数百或数千次迭代。一个复杂的问题不容易理解
对于
后藤
或
呼叫
. 或者换句话说,只使用一个
对于
经常在循环中做一些事情。