标题:求一段VB比较d盘的两个.txt文件并提取不同数据的代码
只看楼主
vbcaonia
Rank: 1
等 级:新手上路
帖 子:97
专家分:0
注 册:2016-5-4
结帖率:100%
已结贴  问题点数:20 回复次数:17 
求一段VB比较d盘的两个.txt文件并提取不同数据的代码
求一段VB比较d盘的两个.txt文件并提取不同数据的代码

附件按钮程序运行速度太慢,请帮我优化一下代码以达到提速的效果或换一种更高效的写法,谢谢  !!!

题意:

1、d盘有两个.txt文件分别为aaa.txt与bbb.txt,两个.txt文件内容格式是一行一个口令。
2、aaa.txt文件逐行在bbb.txt文件中查找对比,当aaa.txt文件某行不存在bbb.txt文件时则将aaa.txt文件中的这一行文本提取到list1。


vb--txt对比.rar (2.36 KB)

搜索更多相关主题的帖子: 文件 aaa txt 提取 代码 
2023-02-04 11:38
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:5 
你的代码,第一次运行时为 0.03秒,其他时间为 0秒,我的代码第一就是 0 秒。
数据量太小,重复100次测速,
我测试的结果是,你的代码 约0.6秒,我的代码 约 0.05秒,10倍的速度差异。
不过,你的代码我没看懂,主要不明白 scripting.dictionary 的用法。你的速度也主要慢在 引用 scripting.dictionary 上面。

另外,遍类二个数组查找的办法,我没去测试,感觉会比字符串直接查找要慢。

程序代码:
 t = Timer
Dim i As Long, j As Long
Dim aa() As String, bb As String

  '打开对比数据
  Open "D:\VBUser\vb--txt对比\bbb.txt" For Input As #1
   '将txt文件内容赋值给数组bb,bb为整个文件内容,不分行
    bb = StrConv(InputB(LOF(1), 1), vbUnicode) '将文件号为1的文件的全部字符转换成国际标准化组织 (ISO) 字符标准后传送给aa
    Close #1
    bb = vbCrLf & bb & vbCrLf   '前后各加一个回车换行符,为后面直接查找创造条件

  '打开对比数据
  Open "D:\VBUser\vb--txt对比\aaa.txt" For Input As #1
   '将txt文件内容赋值给数组aa,aa的元素为txt的一行
    aa = Split(StrConv(InputB(LOF(1), 1), vbUnicode), vbCrLf) '将文件号为1的文件的全部字符转换成国际标准化组织 (ISO) 字符标准后传送给aa
    Close #1

    List1.Clear            '清列表
    For i = 0 To UBound(aa)
        If InStr(1, bb, vbCrLf & aa(i) & vbCrLfb) = 0 Then            'aa行前后加了回车换行符后在bb里直接查找。找不到则添加
            List1.AddItem aa(i)
        End If
    Next i
    
MsgBox "用时 " & Format(Timer - t, "0.00") & ""


[此贴子已经被作者于2023-2-4 12:50编辑过]


授人于鱼,不如授人于渔
早已停用QQ了
2023-02-04 12:40
vbcaonia
Rank: 1
等 级:新手上路
帖 子:97
专家分:0
注 册:2016-5-4
得分:0 
回复 2楼 风吹过b
版主你好,我实际用到的aaa与bbb二个txt文件的总行数分别在800万行左右,我的电脑每次要跑20分钟才有结果,先消化一下你的代码,谢谢!!!
2023-02-04 15:26
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
800万行,
那要注意读文件会不会报内存溢出,如果会,那要换读文件 和 内存数据保存方式。
还有 InStr(1, bb, vbCrLf & aa(i) & vbCrLfb) 这行会不会报错。如果这行报错,那要换 内存数据保存方式和 搜索方式,

继续优化,就是以内存换速度。
那再定义一个 数组 , 如 (浏览器写的代码,未经测试)
dim cc() as string
    redim cc(ubound(aa))
    for i=0 to ubound(aa)
        cc(i)=vbcrlf & aa(i) & vbcrlf    '因数据量超大,把需要查找的数据先组合好来,以空间换速度
    next i

    List1.Clear            '清列表
    For i = 0 To UBound(aa)
        If InStr(1, bb, cc(i)) = 0 Then            '使用aa前后加了回车换行符串在bb里直接查找,空间换速度。找不到则添加
            List1.AddItem aa(i)
        End If
    Next i

授人于鱼,不如授人于渔
早已停用QQ了
2023-02-04 16:51
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
我的方法原理:

总表中保存在内存中,是一个字符串,格式是这个
0D 0A 每行的数据 0D 0A 。。。。。。。 0D 0A
0D0A 回车换行符,对应的常量是: vbcrlf 第一个和最后一个是我们手动添加的。
在 0D0A之间就是每行的数据,
然后 需要查找到的字符,我们加上了 VBcrlf,
0D 0A 每行的数据 0D 0A
查找时,就会匹配到 每行的数据及它的两头的分隔符(VBCRLF)
为什么两头都要加上这个符号呢?防止匹配到不完整的行。如果你数据每行都是等长的,那也可以不再附加分隔符。





授人于鱼,不如授人于渔
早已停用QQ了
2023-02-04 17:17
vbcaonia
Rank: 1
等 级:新手上路
帖 子:97
专家分:0
注 册:2016-5-4
得分:0 
回复 5楼 风吹过b
版主你好,我数据加大到各3万行,用你的方法时间是22秒,用附件中的字典法用时1秒(vb6.0、excel都测了),所以方法有待改进,能在程序中增加某个自定义函数可能会快很多,谢谢!

[此贴子已经被作者于2023-2-4 19:31编辑过]

2023-02-04 19:29
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
VB6本来就不适用于处理大数据量,主要是语言效率问题,最快的就是汇编、C(C++)。
你附件的字典法,引用的是对象,如果一次引用,多次使用。当使用次数超过一定时,就会把因引用对象所消耗的时间补回来。

如你的时间分配:引用对象,可能 是 0.599秒,然后使用只需要 0.00001秒,我测试时也发现这种情况,首次运行时与第二次运行相比,第二次运行时间总是为0,说明时间主要消耗在引用上面。
当数据量一大,引用所花费的时间不变,但使用时间基数极小,成倍增长也不会发生很大的变化。而我写的代码,每次运行的时间比你的时间要长,成倍增长后这个时间就会增长非常多,最终远远超过你的最终时间。

所以大数据量的处理办法,一是改用 C(C++)写,二是使用 C(C++)开发的组件。
而你这个字典就是第二种情况。纯VB6代码,无法在大数据量上的运行速度打败你的方法。
VB6的优点在于 开发简单些的程序  和 小数据量处理 。


授人于鱼,不如授人于渔
早已停用QQ了
2023-02-04 20:03
vbcaonia
Rank: 1
等 级:新手上路
帖 子:97
专家分:0
注 册:2016-5-4
得分:0 
回复 7楼 风吹过b
谢谢!!!
2023-02-04 23:18
冬瓜汤
Rank: 2
等 级:论坛游民
威 望:1
帖 子:15
专家分:75
注 册:2023-1-30
得分:5 
800万行,除了数据库,你有更好的选择吗?这是工具选择的问题,跟编程语言关联并没有那么大。
我见过另一个人是 2亿行的文本 ,和你一样是匹对。文件大小 20几G,有得选吗?除了数据库,几乎没有更好的选择。
2023-02-05 12:53
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
数据库引擎 也是 C/C++ 写的。也是符合我说的第二种情况。
语言还是有关系的,但语言之间可以互相引用组件的,从而减少语言之间的差距。

C语言离硬件非常近,仅次于汇编,但汇编太难学了。所以现在 操作系统级的东西,基本都是 C/C++写的,实在不行,还要在 C/C++ 里内嵌汇编。为啥,离硬件近,效率高。
高级语言为啥高级,因为提供了更好的界面,提供了更多方便的函数。然后这些都是有代价,代价就是编译后的代码运行效率低。
如 i++ ,在C/C++ 里经常用的代码
编译后就是三行汇编,多简洁
mov eax,dword prt[i]
add eax ,1
mov dword ptr[i],eax

vb6里又是怎么样的呢
i=i+1
编译后是什么呢?如果I未定义数据类型,那就是 Variant  
VB6运行时 先判断数据类型,然后不是数据的转化为数据类型,然后再根据数据类型,再决定是生成 add 指令,还是 fadd
这步数就多的去了,速度怎么提得起来。
参看 https://bbs.bccn.net/viewthread.php?tid=510977 四楼的反汇编分析。



授人于鱼,不如授人于渔
早已停用QQ了
2023-02-05 14:07



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-511215-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.541280 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved