[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 15# terse


    是的,磁盘IO性能好的话,速度可能会快一点。
20万个文件频繁读写,时间都浪费在写磁盘上了。
在我的电脑上,机械硬盘,PS脚本大概62秒,GAWK很慢,我没敢测试。

TOP

Test.vbs
  1. Dim myPath, srcFile, dstFolder
  2. myPath  = Left(WSH.ScriptFullName, InStrRev(WSH.ScriptFullName, "\")) '脚本所在路径
  3. srcFile = myPath & "1.txt"                                            '源文本文件
  4. dstFolder = myPath & "result"                                         '目标目录
  5. Dim fso
  6. Set fso = CreateObject("Scripting.FileSystemObject")
  7. If Not fso.FolderExists(dstFolder) Then fso.CreateFolder(dstFolder)   '创建目标目录
  8. Dim c, objDic, objFile
  9. c = 5                                                                 'N选5组合
  10. Set objDic  = CreateObject("Scripting.Dictionary")                    '字典,存放结果
  11. Set objFile = fso.OpenTextFile(srcFile, 1)                            '打开源文本文件
  12. While Not objFile.AtEndOfStream
  13.     Dim strLine
  14.     strLine = objFile.ReadLine                                        '逐行读取源文件
  15.     GetCombination strLine                                            '调用函数
  16. Wend
  17. objFile.Close
  18. Dim dstFile, f
  19. For Each key In objDic.Keys
  20.     dstFile = dstFolder & "\" & Right("000000" & key, 6) & ".txt"     '目标文件名
  21.     Set f = fso.OpenTextFile(dstFile, 2, True)
  22.     f.Write(objDic.Item(key))                                         '写入目标文件
  23.     f.Close
  24. Next
  25. Function GetCombination(strLine)
  26.     Dim key, str, i
  27.     key = 1
  28.     str = ""
  29.     For i = 1 To Len(strLine)                  'str赋值:11111000000000000000000000000000 共32位
  30.         If i <= c Then
  31.             str = str & "1"
  32.         Else
  33.             str = str & "0"
  34.         End If
  35.     Next
  36.     If Not objDic.Exists(key) Then objDic.Add key, ""
  37.     objDic.Item(key) = objDic.Item(key) & Left(strLine, c) & vbCrLf   '字典,赋初始值
  38.     Dim reg
  39.     Set reg = New RegExp                                              '创建正则表达式
  40.     reg.Pattern = "(1)(0)(?=(0*))\3(?=(1*))\4$"
  41.     While InStr(str, "10") > 0
  42.         Dim s
  43.         s = ""
  44.         str = reg.Replace(str, "$2$1$4$3")                            'str值交换 10 <--> 01
  45.         For i = 1 To Len(str)
  46.             If Mid(str, i, 1) = "1" Then s = s & Mid(strLine, i, 1)   '查找"1"与strLine对应的字符
  47.             If Len(s) = c Then Exit For                               '找到5个,退出For
  48.         Next
  49.         key = key + 1
  50.         If Not objDic.Exists(key) Then objDic.Add key, ""
  51.         objDic.Item(key) = objDic.Item(key) & s & vbCrLf              '字典,赋值
  52.     Wend
  53. End Function
  54. MsgBox "Done"
复制代码
1

评分人数

TOP

回复 9# WHY
感谢!
经过测试,该 PowerShell 脚本,处理十几行的数据非常迅速,但处理成千上万行数据,读入内存的耗时让人崩溃。
欲提高 PowerShell 脚本的效率,研究过类似下列网页的文章,还是不得要领,恳望指点。
https://www.pstips.net/speeding-up-powershell-multithreading.html

TOP

回复 17# WHY
感谢!
处理成千上万行数据,同样存在读入内存耗时漫长的状况。

TOP

本帖最后由 WHY 于 2023-3-3 16:12 编辑

回复 18# 思想之翼


    这个问题得看电脑硬件配置了,我的电脑配置不咋地,多线程没想去玩。
每一行数据要循环处理201376次,然后又要写磁盘201376次,如果有10000行数据,别指望能快到哪去。

改一下,每读取2行数据开始写磁盘,减少循环等待时间及字典空间占用,我没有过多测试。你试试吧。
  1. Dim myPath, srcFile, dstFolder
  2. myPath  = Left(WSH.ScriptFullName, InStrRev(WSH.ScriptFullName, "\")) '脚本所在路径
  3. srcFile = myPath & "1.txt"                                            '源文本文件
  4. dstFolder = myPath & "result"                                         '目标目录
  5. Dim fso
  6. Set fso = CreateObject("Scripting.FileSystemObject")
  7. If Not fso.FolderExists(dstFolder) Then fso.CreateFolder(dstFolder)   '创建目标目录
  8. Dim c, objDic, objFile
  9. c = 5                                                                 'N选5组合
  10. Set objDic  = CreateObject("Scripting.Dictionary")                    '字典,存放结果
  11. Set objFile = fso.OpenTextFile(srcFile, 1)                            '打开源文件
  12. Dim num, strLine
  13. num = 0
  14. While Not objFile.AtEndOfStream
  15.     num = num + 1
  16.     strLine = objFile.ReadLine                                        '逐行读取源文件
  17.     GetCombination strLine, c, objDic                                 '求组合
  18.     If num Mod 2 = 0 Then                                             '每读取2行开始写入文件
  19.         SaveToFile objDic
  20.         objDic.RemoveAll                                              '清空字典
  21.     End If
  22. Wend
  23. If objDic.Count > 0 Then SaveToFile objDic                            '字典不为空,写入文件
  24. objFile.Close
  25. Function SaveToFile(ByRef oDict)
  26.     Dim key, dstFile, f
  27.     For Each key In oDict.Keys
  28.         dstFile = dstFolder & "\" & Right("000000" & key, 6) & ".txt" '目标文件名
  29.         Set f = fso.OpenTextFile(dstFile, 8, True)
  30.         f.Write(oDict.Item(key))                                     '写入目标文件
  31.         f.Close
  32.     Next
  33. End Function
  34. Function GetCombination(ByRef strLine, c, ByRef oDict)
  35.     Dim key, str, i
  36.     key = 1
  37.     str = ""
  38.     For i = 1 To Len(strLine)                  'str赋值:11111000000000000000000000000000 共32位
  39.         If i <= c Then
  40.             str = str & "1"
  41.         Else
  42.             str = str & "0"
  43.         End If
  44.     Next
  45.     If Not oDict.Exists(key) Then oDict.Add key, ""
  46.     oDict.Item(key) = oDict.Item(key) & Left(strLine, c) & vbCrLf     '字典,赋初始值
  47.     Dim reg
  48.     Set reg = New RegExp                                              '创建正则表达式
  49.     reg.Pattern = "10(?=(0*))\1(?=(1*))\2$"
  50.     While InStr(str, "10") > 0
  51.         Dim s
  52.         s = ""
  53.         str = reg.Replace(str, "01$2$1")                              'str值交换 10 <--> 01
  54.         For i = 1 To Len(str)
  55.             If Mid(str, i, 1) = "1" Then s = s & Mid(strLine, i, 1)   '查找"1"与strLine对应的字符
  56.             If Len(s) = c Then Exit For                               '找到5个,退出For
  57.         Next
  58.         key = key + 1
  59.         If Not oDict.Exists(key) Then oDict.Add key, ""
  60.         oDict.Item(key) = oDict.Item(key) & s & vbCrLf                '字典,赋值
  61.     Wend
  62. End Function
  63. MsgBox "Done"
复制代码
1

评分人数

TOP

返回列表