|
|
导航: |
论坛 -> DELPHI技术
斑竹:liumazi,sephil |
|
作者: |
|
2019/11/20 15:26:44 |
标题: |
小菜鸟 记录一次Delphi C# Hash性能对比? |
浏览:2783 |
|
加入我的收藏 |
楼主: |
起因: 百万文本行txt去重 实现方案: 利用哈希表[Dictionary]的特性实现。
先看.net的
然后看Delphi的
不要吐槽我的代码乱哈。
只是一个简单对比。
测试文件 275M txt 问本行650W左右
性能数据: C# 去重耗时 2200ms Delphi 去重耗时 8800ms
竟然差距有4倍。另外测试了一个20W 数据的 差距有7 8倍。
不知道有和办法调优?或者 无能为力?
----------------------------------------------
- |
作者: |
|
2019/11/20 15:27:40 |
1楼: |
C#代码 使用Hashtable 和Dictionary 性能一致 没有啥差距。
----------------------------------------------
-
|
作者: |
|
2019/11/20 16:27:12 |
2楼: |
建议把输入输出的时间去掉,只比较Hashtable 和Dictionary加入的时间,跟能把问题性能点找出来。另外,你比较的时候,写法上也略有不同,可能也有区别。。。
----------------------------------------------
-
|
作者: |
|
2019/11/20 16:44:54 |
3楼: |
用指针读取,你会发现性能可以提升一大截.
----------------------------------------------
相信自己,若自己都不相信,那还有谁可信。
|
作者: |
|
2019/11/20 17:58:05 |
4楼: |
@letianwuji
意思是 StreamReader 性能有差距?
----------------------------------------------
-
|
作者: |
|
2019/11/20 18:12:45 |
5楼: |
最新测试结果: 使用StreamReader Readline 不作处理 读完为止 使用TextFile Readln 读完为止
耗时都要6秒多。问题出在这里。 而C# StreamReader 读完为止 只需要200ms
----------------------------------------------
-
|
作者: |
|
2019/11/20 19:24:37 |
6楼: |
C#是不是采用了内存缓冲(内存文件映射)读取?而Delphi是从文件直接逐行读取的?可以关注一下二者的内存消耗量!
----------------------------------------------
-
|
作者: |
|
2019/11/20 19:38:25 |
7楼: |
@arhaha
没有内存映射。
我对比了两边的StreamReader 实现 基本都差不多
发现了一个区别。
这是Delphi的 这是C#的
Delphi不知道是为了方便 每次读取都把缓存里的已读部分移除掉 这样copy的时候就是从0开始
而C# 则不做移除的处理
不晓得是不是这个原因了。
本人水平有限 无法继续深入了。。。有没有大神继续深入下看看
另外:create的时候buffsize参数 使用C#的1024 效率有所改善从6秒+降低到了5秒+
----------------------------------------------
-
|
作者: |
|
2019/11/20 20:34:58 |
8楼: |
强烈建议测下 http://bbs.2ccc.com/topic.asp?topicid=564997 的lookup3.c delphi 有自带Delphi版
----------------------------------------------
[alias] co = clone --recurse-submodules up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
|
作者: |
|
2019/11/20 20:48:41 |
9楼: |
@keymark 技术有限 完全不懂。。。
----------------------------------------------
-
|
作者: |
lsuper (lsuper) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2019/11/20 22:41:58 |
8楼: |
可以 aqtime 看看,代码附件发出来?
----------------------------------------------
-
|
作者: |
|
2019/11/20 22:52:32 |
10楼: |
其实,你可以试试把 TStreamReader 换成 TStringList
然后 SReader := TStringList.Create; SReader.LoadFromFile('D:\1.txt'); for var I := 0 to SReader.Count - 1 do SReader[I];
大概这样搞,你会发现,速度就正常了。
----------------------------------------------
-
|
作者: |
|
2019/11/20 23:01:11 |
11楼: |
@lsuper
工程我放在附件里这个帖子
----------------------------------------------
-
|
作者: |
|
2019/11/20 23:01:59 |
12楼: |
@crystalmoon
已经测试过 是StreamReader读取影响速度
Dictionary 差距不大。
现在问题就在于这个了
----------------------------------------------
-
|
作者: |
|
2019/11/21 0:03:36 |
13楼: |
StreamReader应该是临时工写的。请谅解。。。你的场景里,就像我说的,可以用TStringList无痛替换。速度就正常了。
----------------------------------------------
-
|
作者: |
|
2019/11/21 0:37:33 |
14楼: |
@crystalmoon stringlist就等于吧所有数据先读入内存了。 这里非常耗时吧 我猜测。
而我对比的C#的 读入+去重 =2200ms
----------------------------------------------
-
|
作者: |
hs_kill (lzl_17948876) |
★☆☆☆☆ |
-
|
普通会员 |
|
2019/11/21 10:07:46 |
15楼: |
stringlist.LoadFromFile 内部用的是filestream 也就是文件映射
----------------------------------------------
http://www.cnblogs.com/lzl_17948876/
|
作者: |
|
2019/11/21 10:21:18 |
16楼: |
把 TStreamReader 和 TStreamWriter 里面的 TFileStream 替换成 TBufferedFileStream ,写入速度提高显著。由于 TStreamReader.ReadLine 没有用 TBufferedFileStream 的 Read 方法,速度一样。 如果用 TStreamReader.ReadBlock 则速度提升了。
下图是未修改 TStreamReader 和 TStreamWriter 的测试结果:
此帖子包含附件:
大小:56.6K |
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
|
作者: |
|
2019/11/21 10:22:00 |
17楼: |
下图是将 TFileStream 替换成 TBufferedFileStream 后的结果
此帖子包含附件:
大小:65.6K |
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
|
作者: |
|
2019/11/21 16:45:19 |
18楼: |
@chencong5025 不用猜, 你试试就知道。 耗时主要在于 readline,stringlist 用 索引读,反而快。
----------------------------------------------
-
|
作者: |
|
2019/11/21 16:58:07 |
20楼: |
@earthsbest 看他的内容情况了。我昨天测试了 650W行的简单的文本(每行都是“这是一行测试文本”),还好。
另外 @chencong5025 全能的测试中,如果你不像改代码,可以自己先建立一个TBuffterFileStream,然后用另一个Create重载,把这个Stream赋值给StreamReader就可以了。不过,对你的Readline,基本毋加成。原因,全能已经说了。
反正,官方的 Readline 里的最后三句,太流氓了。 Result := FBufferedData.ToString; SetLength(Result, NewLineIndex); FBufferedData.Remove(0, PostNewLineIndex); 所以。我说他是临时工写的。
当然,就像全能说的,Stringlist比较耗内存,毕竟是一次性加载到内存了。太大的不行,你要评估下你的内存和文本。。。
----------------------------------------------
-
|
作者: |
|
2019/11/21 18:44:50 |
21楼: |
@crystalmoon 结论就是 现有的情况下 无法改进= =#
除非 修改VCL
----------------------------------------------
-
|
作者: |
|
2019/11/21 20:37:34 |
22楼: |
可以第三方(比如 MGSoftt的MGTextReader) ,或者自己改进Reader。。不需要一定要改vcl,可以自己继承或者helper
----------------------------------------------
-
|
作者: |
|
2019/11/22 15:50:55 |
23楼: |
谁有账号的可以提交个QC。。 这StreamReader的代码质量 真的是无语
----------------------------------------------
-
|
作者: |
|
2019/11/22 16:06:22 |
24楼: |
楼上,账号不花钱。 凡是 申请过 社区版的,自动拥有 QC 账号。
----------------------------------------------
(C)(P)Flying Wang
|
作者: |
|
2019/11/22 21:13:50 |
25楼: |
@wang_80919 @crystalmoon @earthsbest https://quality.embarcadero.com/browse/RSP-26958 已经提交 去投个票啥的 哈哈
----------------------------------------------
-
|
作者: |
|
2019/11/25 11:11:49 |
26楼: |
这类问题,解决的可能性都是排在比较低的位置。群里我和你提到过临时的简单办法,你可以先将就下。。减少一半也是好的。 发现模仿Net的几个类的实现,都是“可用”而已,用了就不要讲究性能。
----------------------------------------------
-
|
|