作者:
2021/12/2 20:38:06
2楼:
单独的回车不应该算一个新行,除非是在MAC上…… 因为理论上换行符: Windows用:【回车换行】也就是【0D0A】或者【#13#10】,【\r\n】,【CRLF】 Linux用:【换行】。 MAC用:【回车】。 如果不那么严谨则控件开了Wordwarp,都可以算新的一行。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/3 7:07:22
3楼:
Delphi11源码(TStringList 可以人为定义换行符,默认是#13#10):
此帖子包含附件: 大小: 49.5K
----------------------------------------------
武汉天气不好
作者:
2021/12/3 7:41:05
4楼:
procedure TForm1.Button1Click(Sender: TObject); var FMyTextFile : TextFile; // just for Text file (plain text) FMyBufferString: string; // if you want have a text in each line readed FMyTotalLines : integer; FMyFileSize : integer; begin FMyFileSize := 0; FMyTotalLines := 0; // AssignFile(FMyTextFile, 'E:\Data.txt'); try Reset(FMyTextFile); FMyFileSize := FileSize(FMyTextFile); // while not EOF(FMyTextFile) do begin inc(FMyTotalLines); // Readln(FMyTextFile); // just advance to next line // //Readln(FMyTextFile, FMyBufferString { just for read the line and advance it } ); end; // finally CloseFile(FMyTextFile); // ShowMessage( { } Format('File size: %d, Total lines: %d', [ { } FMyFileSize, { } FMyTotalLines { } ]) { } ); end; end; To determine the end-of-line you can use: System.System.SetLineBreakStyle(var T: Text; Style: TTextLineBreakStyle); tlbsLF = Linefeed only tlbsCRLF = Carriage return followed by Linefeed
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
2021/12/3 7:52:49
5楼:
@emailx45: If there is no SetTextBuf(FMyTextFile, Buffer); Readln will be slow. I test on win10x64.
----------------------------------------------
武汉天气不好
作者:
2021/12/3 7:56:59
6楼:
READLN() is very quick for me in my i7 4770K MSWindows 10 1.000.000 lines in < 1 second
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
2021/12/3 8:02:52
7楼:
The count by Readln is also different from that count by TStringList. FileStream method is best.
此帖子包含附件: 大小: 13.1K
----------------------------------------------
武汉天气不好
作者:
2021/12/3 8:15:04
8楼:
look, readln() is based on MSWindows API not Delphi. so... the MS is wronged another again?
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
2021/12/3 8:22:51
9楼:
readln source code:
此帖子包含附件: 大小: 61.1K
----------------------------------------------
武汉天气不好
作者:
2021/12/3 10:25:17
10楼:
----------------------------------------------
-
作者:
2021/12/3 10:26:29
11楼:
前些天做的文本文件分割,去重复,用字典大文件也很快
----------------------------------------------
-
作者:
2021/12/3 14:00:06
12楼:
其实行数有差异是正常的,看怎么定义什么是一行。 不考虑苹果电脑的话,还是只看换行符比较靠谱【\n】,不用考虑回车。 函数setTextBuffer的确对文本有用,不过缓存太大太小都不行,我记得16到32kb左右比较合适,但是我看了下实际的项目,似乎只在输出文件时setTextBuffer了……呃…… 读的时候用的是基于TStream的自己的类,稍微快一点点。 Delphi很神奇,20年前它应该是最快的,而现在读文本无论啥Reader,Stream的ReadLn,TEXTFILE的ReadLn都不太快(对比其它语言)。各种方法里面ReadLn算最快的了…… 最后测试需要注意外部条件,因为很多大多文本文件相对来说太小了。 跑第二次,基本都全加载都内存里面了。 不知道大家觉得文本文件多大算大,我这里单个5GB,6GB都有,不过很多厂商都怀旧拆分了。比如原始应该是70GB的文本,传过来都是分成2GB一个个的一堆编号文件了。 最后,对比其它语言,Delphi文本操作真的太慢了。 不知道有没有人试过,Delphi开多线程读多个文件,和单线程顺序读简直没区别。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/3 14:02:28
13楼:
呃是:setTextBuf 不是:setTextBuffer -__- 怎么总打错。。。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/3 14:58:53
14楼:
我测试下来,GetTextLineCount_FS 函数性能还可以。 600M 文本文件,14181548 个文件,用时 1659 毫秒。不算慢吧? (如果把位置信息也保存下来,快速定位行也搞定了) CPU 够快,但磁盘 IO 肯定没有那么快。 如果要说慢,肯定是思路问题。和语言无关。
----------------------------------------------
武汉天气不好
作者:
2021/12/3 16:29:12
15楼:
“14181548 行”,不是“14181548 个文件” 写错了。sorry。
----------------------------------------------
武汉天气不好
作者:
2021/12/3 17:00:45
16楼:
Delphi 源代码真的是个宝藏。值得多看看! Delphi 源代码真的是个宝藏。值得多看看! Delphi 源代码真的是个宝藏。值得多看看! 三遍!!! 举一个亲身经历的例了: 我在学习 SIMD 指令时,针对一个 4096X4096X32bits 的位图进行任意角度旋转。 我的目标是希望优化到 20 毫秒以内。10 毫秒以内最佳。 但是,无论我如何优化,都在 30 毫秒以上。 一气之下,我注释了所有旋转代码。依然需要 30 毫秒! 最终发现,Delphi 在内存中,创建一个 4096X4096X32bits 的位图需要 30 毫秒。 为什么呀?我在内存中创建,又不是在磁盘上。 调试进 Delphi 源代码 Vcl.Graphics.pas 中,终于发现: 位图创建完毕后,Delphi 多做了一步,将画布置成白色, 当刚创建好的时候,画布默认是黑色(内存全零,当然是黑色了): “PatBlt(NewImageDC, 0, 0, bmWidth, bmHeight, WHITENESS);” 而我们习惯,在自己的代码中,又将画布置成黑色: “bmp.Canvas.FillRect(bmp.Canvas.ClipRect);” 多了俩步操作,就多出来这个 30 毫秒时间了。 将 Vcl.Graphics.pas 中,这个画布置成白色的代码注释掉, 再将自己代码中,画布置成黑色的代码注释掉, 创建一个 4096X4096X32bits 的位图,画布默认为黑色,用时就只需要 0 毫秒了。 源代码地址:https://github.com/dbyoung720/ImageGray.git
----------------------------------------------
武汉天气不好
作者:
2021/12/3 18:54:58
17楼:
@dbyoung 我的项目不是取得行数,是需要处理每一行的数据…… 举个实际的例子: 总共722MB文本,4个文件。类似csv格式,1行大概100个字符(字节),4个字段。 稍微需要判断一下每个字段情况比如第二个字段是B=xxxxx还是A=XXXXX, 然后几个小判断后,每行输出到另一个文本。 测试几台机器,不同的操作系统,最快的同一台Windows机器呢: Delphi大概10秒,Go可以不到2秒,Java3-4秒,C++呢5-8秒。 除了Delphi,其它语言无论Windows还是CentOS下,多线程都稍快一些。 而Delphi的程序,Windows下单多线程无区别10秒,CentOS下多线程可以到6秒。 都是运行N次看结果,这个数据量,多运行几次可以忽略磁盘IO和偶然误差。 因为逻辑真的很简单,所以我觉得不会是你说的“肯定是思路问题。和语言无关”。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/3 19:05:32
18楼:
PS:大概15年前,也测过Delphi7读写文本,当时对比的是C++(可能是VC6.0一类编译的,记不清楚了)。 那时候Delphi明显快过C++,无论是读文本,还是简单的数学运算,甚至空循环运行1000W次这种。因为性能很重要,所以一直用的Delphi。 我们不是测一下就完事儿,有些必须C++的项目,也试过C++的流,和纯C的读写。 我们也知道简化流程,专注一点,避免干扰,多设备多次数。。。 现在感觉Delphi慢,只是因为别的语言进步太大了。 有兴趣可以试试Hashmap类的容器,还是Go快不少,甚至Java内存给得足都更快(-Xmx9216m -Xms9216m 这种不要它老回收)。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/3 21:58:32
19楼:
上面争论了这么多,有没有考虑过读写都用自己的大缓存呢?大数据读写,不用自己的缓存,我自己都不习惯。另外一个就是用映射文件MappedFile。影响速度的,主要在磁盘IO,所以要把磁盘IO次数尽量减少。
----------------------------------------------
-
作者:
2021/12/6 10:00:47
20楼:
@arhaha 文件不太大的话,几百兆的话,第二次就全部进缓存了,这是操作系统干的事儿(也可能是SSD自己干的)。我观察到现象是这样的。 而且LZ测试方法,测试结果都是正确的,没什么问题。 根据LZ的测试结果,用FileStream去寻找回车换行符,其实也挺快的。 我仅提出一个观点:在Windows/Linux上,应该仅考虑换行符(\n),不考虑回车符。 理论上应这样,但是单回车符算不算产生新的一行,要看实际业务逻辑。 顺便感叹了一下Delphi效率相对没以前高了。 后来又想到一个小问题,Readln和从Stream里面查找对比,不太公平。 对TEXTFILE进行ReadLn,应该对应TStreamReader.ReadLine。 而BlockRead,才对应TFileStream.Read。.
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/6 13:43:12
21楼:
楼上,你所谓的Delphi速度慢,根据我的判断,其实就是申请和释放内存慢。你有没有试过10.3或者10.4(可能从10.2开始了),因为我记得delphi专门就这个问题优化过。比如你需要110M内存,当超过100M的时候,RTL直接给你申请200M,这样的不慢才怪呢。 另外再给你一个建议,测试里不要包括释放内存。因为java/go是是耍赖,实验做完了,但是内存以后再释放、不被包括在实验里,直接节省几十秒时间。至于你说的C++快,我就不懂了,为什么快?这个就只能等你的解释了。 最后,不知道你有没有使用replace函数,如果使用了,那不妨再测一下,这个函数经过大幅优化,快了10倍之多。 不过Delphi效率相对没以前高也是有可能的,建议你试试XE,那是最后一个纯windows平台的版本,它的编译器和RTL可以随便使用win汇编,不像后来的版本,为了跨平台必然牺牲效率. 同时也可以试试XE2,这个版本改成x64编译器的时候,不知道效率是进步了,还是退步了,都有可能。 至于后面的版本,编译器效率肯定是退步了,这个不用想,但RTL和内存管理却是可以持续进步的,特别是从10.3开始,进步比较大,值得一试。 有空的话,等你的测试结果哦!
----------------------------------------------
只有偏执狂才能生存!
作者:
2021/12/6 16:55:44
22楼:
@nevergrief 我也很希望是我哪里没考虑周全…… 可是这些项目做了10多年了,时不时的都会想再看看,在试试。 比如上面提到的纯文本的读写,自己写个类,当时确实快了不少。 自以为处理得不错,后来才发现要兼容GBK,UTF8……改吧,兼容了,速度也和Delphi自带的基本没区别了。 至于内存方面,不会new delete几千万次。自己管理,分布申请,计算位置向里面放就会快很多。也不会给Hashmap设置不合理的初始大小等等。 哎,我只想表达各方面都想过了,试过了,还没发现大家提到哪一点是没想到的。 但是这边Delphi绞尽脑汁,那边Go嗖一下就运行完了……打击很大啊。 Delphi新版公司没买,只能个人试着用,不能用在项目上。 试过在基本的文本读写上和Delphi7速度差不太多。 其实感兴趣大家可以试试楼主的例子,没内存操作,就按行读文本,看看Go是不是很快。 至于C++,有些项目必须要用,没太多时间去慢慢试。 过去加目前结论是,简单的文件读写,自带的Hashmap类容器: 1)Delphi7 明显快过 VC6.0(不清楚C++标准,可能是98?) 2) Delphi10.x 稍不如 VS2022(默认C++14)
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/6 17:25:54
23楼:
我怎么错别字好多啊…… 总之公司已经不用Delphi了,仅维护老项目。 后台用C++, Java, Go。 界面全部转WEB,当然Java,springboot jquery mybatis……bla bla bla 其实也没那么严谨,比如某个只能C++的项目需要个界面,也只能QT。 不算大数据那些,技术栈已经太多,还招不到人…… 至于为什么不用Delphi,呵呵Embarcadero那连绵不绝的律师信起了很大作用。 那时候不是Embarcadero,我才到公司不太清楚。 后来Embar来了,说超过授权数量,公司又买了几套。 还是说超过授权数量,公司开始内部查谁在乱用,改WIFI密码怀疑是隔壁蹭网的在用。然后继续收律师信,超过授权数量。 收了好多年,才反应过来,他们是群发啊。 老板很不开心,正好要转Linux,就决定不用Delphi了,律师信还来。 快完全不用了,律师信还来。 前些年当面和他们亚太地区的老大反应过,他说这种诈的方式确实不应该,以后经营模式不会这样了,让我们用Delphi的要有信心。。。完了律师信还来。 又给他写了邮件反馈,估计离职了吧?反正律师信还来。 没回信,还顺便定期给我邮箱发广告。 好想叫他们人过来,自己数一数我们公司有几个开发,几个在用Delphi,自己算算超出授权几个了…… 真是一顿操作猛如虎,一看比分0比5。 Delphi这么好的开发工具,现在弄成这样,他们公司功劳不小。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/6 22:58:52
24楼:
上面某楼的还是没有理解我的意思。即使操作系统帮你做了缓存,请问,你难道不是还是要调用操作系统的API来获取数据吗?极端情况,我每次读一个字节,每一次都调用操作系统的API,这个调用不花时间吗?自己缓存的意思,就是一次性从操作系统那里获取xx KBytes的数据到我申请的内存中,以后使用这部分数据,就像从一个数组中读取一样的,根本无需向操作系统索取了。这样的方法,对大量数据的操作,是必须的!!!!!!
----------------------------------------------
-
作者:
2021/12/7 10:19:06
25楼:
@arhaha 你好,虽然我回的是其它人的帖子,但是也提到了自己管理内存。 你说的这些是基本操作啊。 我又不能贴源代码证明(虽然我也很想),顺便让大家找问题,优化。 只靠论坛是说不清楚的,不妨用楼主的例子: 自己生成个600MB的文本文件,用楼主的代码统计行数,校准本机的耗时(设法避免电脑性能差异)。 然后设法优化,看能不能比楼主的快。 再看看Go不做任何优化,就一行行读,需要的时间是多少。 最后试一下我说的例子,把600MB的文本弄成4字段的csv,1行大概100个字符(字节),4个字段。 稍微需要判断一下每个字段情况比如第二个字段是B=xxxxx还是A=XXXXX。把满足条件和不满足条件的分别输出到2个文本。 看看同样的逻辑Delphi7/11要多久,Go要多久。 自己实验才是最可靠的。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/7 10:49:44
26楼:
哎,多说无益…… 改了一个Go的统计行数程序,试了一下我的文件。 700MB,744万行,0.6秒不到。
此帖子包含附件: 大小: 56.8K
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/7 10:57:00
27楼:
Go代码如下: 因为是在项目框架内改的程序,有些冗余的代码,删除即可。 没做任何优化。就是一行行读而已。 package main import ( "bufio" "bytes" "fmt" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" "io" "io/ioutil" "os" "path" "path/filepath" "runtime" "strings" "time" ) const AppName = "取得文本行数" const AppVersion = "3.30.01" //const AppCode ="LineCount" var doFileList []string var subCount int func DoOneFile(number int,SourceFile string) { ConsoleWriteLnGBK("%d: Counting: %s...",number,path.Base(filepath.ToSlash(SourceFile))) fi, err := os.Open(SourceFile) if err != nil { panic(err) } defer func(f *os.File) { err := f.Close() if err != nil { } }(fi) reader := bufio.NewReader(fi) var aCount =0 for { _,_, err := reader.ReadLine() if err == io.EOF { break } if err != nil { panic(err) } aCount++ } ConsoleWriteLnGBK("%d: Done: %s: %d line(s).", number,path.Base(filepath.ToSlash(SourceFile)),aCount) subCount+=aCount } func DoOnePath(SourcePath string) { fileInfoList, err := ioutil.ReadDir(SourcePath) if err != nil { panic(err) } for i := range fileInfoList { if !fileInfoList[i].IsDir(){ doFileList = append(doFileList,filepath.Join(SourcePath, fileInfoList[i].Name())) } } } func ConsoleWriteLnGBK(aContent string, a ...interface{}) { if strings.ToLower(runtime.GOOS[0:3])=="win" { b, _ := ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(fmt.Sprintf(aContent, a...))), simplifiedchinese.GBK.NewEncoder())) _, err := os.Stdout.Write(b) if err != nil { fmt.Printf("Error: %s\n", aContent) fmt.Printf("Error: %s\n", err) os.Exit(1) } fmt.Printf("\n") }else{ fmt.Printf(aContent+"\n", a...) } } func main() { defer func() { if err := recover(); err != nil { ConsoleWriteLnGBK("Error: %s", err) os.Exit(1) } }() t1:=time.Now() //Golang only support UTF8,but our workflow platform only support GBK。。。 //fmt.Fprintf(os.Stdout, "%s %s\n",AppName, AppVersion) ConsoleWriteLnGBK("%s %s", AppName, AppVersion) if cap(os.Args) < 7 { panic("Program Params not enough!") } InputPath := os.Args[1] //WorkPath := os.Args[2] //TaskID:= os.Args[3] //InstanceID:= os.Args[4] //ImplementID:= os.Args[5] fRuleName := os.Args[6] fRuleVersion := os.Args[7] if fRuleName != AppName { panic(fmt.Sprintf("Name not match! db:%s app:%s !", fRuleName, AppName)) } if fRuleVersion != AppVersion { panic(fmt.Sprintf("Version not match! db:%s app:%s !", fRuleVersion, AppVersion)) } fmt.Println(runtime.GOOS+" "+runtime.GOARCH+" "+runtime.Version()) paths := strings.Split(InputPath, "|") for _, pathOne := range paths { if len(pathOne) > 0 { DoOnePath(pathOne) } } for i := range doFileList { DoOneFile(i,doFileList[i]) } ConsoleWriteLnGBK("Total lines: %d.", subCount) ConsoleWriteLnGBK("Time elapsed: %s", time.Now().Sub(t1)) fmt.Printf("Finish:\n") }
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/7 11:13:25
28楼:
用Go测了几个文件,测试2主要想看看文件数量影响速度么,结果如下: 程序是单线程,见上面代码,多个文件可多线程优化速度。 722MB(4个文件),744万行,0.590秒。 722MB(1个文件),744万行,0.586秒。 688MB(20个文件),2488万行,0.742秒。 5.86GB(1个文件),1亿4565万行,5.66秒。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/7 11:49:54
29楼:
上面是Windows 10,i7-10870H+西数SN730。 用同一台笔记本WSL2下的Ubuntu测试结果: 722MB(4个文件),744万行,0.255秒。什么鬼……
此帖子包含附件: 大小: 87.1K
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/7 12:03:52
30楼:
继续Linux: 5.86GB(1个文件),1亿4565万行,2.54秒。 不想再测了, 同时回应一下上面哪位同学说Java和Go的问题。 Java因为JVM,不能认为程序结束内存就释放完了。非常对。 但Go编译的是原生程序,进程都退出了,没道理说它内存是以后再释放的哦。 PS:上面行数的测试,和内存无关。。。
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/8 10:08:46
31楼:
这Go的效率简直太强了,我之前做一个http的api,开始是用delphi,用各种线程池各种优化,过不了压测,后来用go写了个简单的...没点问题,还有用go写日志也是
----------------------------------------------
-
作者:
2021/12/8 11:06:02
32楼:
楼上,这个应该不是狗好,是狗的库优化得好?
----------------------------------------------
-
作者:
2021/12/8 11:16:16
33楼:
@drfan (若苗瞬) 我在 Win10X64 下,VSCode 打开你上面给出的代码: 错误如下图,参数应该如何传入(test.txt 在当前目录下。F:\test)?谢谢。
此帖子包含附件: 大小: 64.5K
----------------------------------------------
武汉天气不好
作者:
2021/12/8 11:42:31
34楼:
@dbyoung 参数1:输入目录 参数2:执行目录(输出目录) 参数3,4,5没用到。 参数6:名称 参数7:版本 命令行大概这样,注意参数是目录,不是文件: “InPath WorkPath 1 1 1 取得文本行数 3.30.01”
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/8 11:55:19
35楼:
再废话几句。 Go的线程,通道,真的太好用了。 上面的例子如果是处理多文件,还可以再快一些。 N个文件就用N个线程(协程)读。 正常项目是有结果的,所以N个现场都把处理的结果放入通道。 多种结果就放多个通道。 每个通道有个专门写的线程。 处理数据,奇快无比。 然后Delphi多线程本身写起来就麻烦一些,也没有通道这概念。 找了网上一些FIFO的队列,包括环形缓存,虽然这些大神已经写得很好很完美了,但是速度和Go对比起来还是差别巨大。 Go我是新手,只会每个线程对应一个文件,不清楚如果单文件很大,比如前面5GB多那种,能怎么弄。PS:今年负责C++和Go的小伙子都辞职了,找不到人问,必要的话只能自己研究。 吃完饭我弄个多线程版本试试……
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/8 12:00:57
35楼:
OK。运行成功。谢谢。
此帖子包含附件: 大小: 13.5K
----------------------------------------------
武汉天气不好
作者:
2021/12/8 12:36:13
36楼:
…… 被禁用帐号,帖子内容自动屏蔽! ……
----------------------------------------------
该账号是个傻逼
作者:
2021/12/8 13:22:17
37楼:
@dbyoung 我看日志只有1018毫秒。 而且你别统计go和exe文件啊,目录里只留txt。 把打印输出转GBK的地方,都改为【fmt.Printf】,显示中文就不会乱码了。 试了下多线程, 这速度超过我的SSD理论速度了, 只能认为解压后被缓存到内存咯:722MB(4个文件),744万行: Win:0.590秒(多线程0.218秒)。Linux:0.255秒(多线程0.117秒)。722MB(1个文件),744万行: Win:0.586秒。688MB(20个文件),2488万行: Win:0.742秒(多线程0.228秒)。Linux:没测单线程(多线程0.149秒)。5.86GB(1个文件),1亿4565万行: Win:5.66秒。Linux:2.44秒。
此帖子包含附件: 大小: 23.5K
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/8 14:02:19
38楼:
看了一下 GO 的 readline 源码,原理好像和 Delphi 的不太一样。 再次谢谢楼上。
此帖子包含附件: 大小: 7.9K
----------------------------------------------
武汉天气不好
作者:
2021/12/8 14:21:28
39楼:
如果只统计 #10 作为换行,Delphi 比 GO 还要快。
此帖子包含附件: 大小: 40.3K
----------------------------------------------
武汉天气不好
作者:
2021/12/8 23:19:52
40楼:
…… 被禁用帐号,帖子内容自动屏蔽! ……
----------------------------------------------
该账号是个傻逼
作者:
2021/12/10 0:08:12
41楼:
如果只统计 #10 作为换行,Go的代码也需要调整。 新的方式稍快一些,但只能统计行数,无法进一步处理每一行数据了。 我小测的结果(没测buffer大小是否有影响):722MB(1个文件),744万行: Win:0.586秒 --> 0.459秒(仅统计#10)。5.86GB(1个文件),1亿4565万行: Win:5.66秒 --> 3.84秒(仅统计#10)。 部分代码如下,注释掉的就是原来的ReadLine方式: reader := bufio.NewReader(fi) var myBuffer = make([]byte, 655350) var aCount =0 for { i,_ := reader.Read(myBuffer) j:=0 for { if j>= i { break } if myBuffer[j] == '\n' { aCount++ } j++ } if i<655350 { break } //用读行的方式来判断行数。 //_,_, err := reader.ReadLine() //if err == io.EOF { // break //} else if err != nil { // panic(err) //} //aCount++ }
此帖子包含附件: 大小: 16.0K
----------------------------------------------
Bye bye DDRFAN...
作者:
2021/12/10 12:34:48
42楼:
这些问题没什么意义。请问什么场景下需要考虑这些边角的性能问题? 内存分配释放影响性能? 什么场景需要考虑这问题。 强迫症发作?
----------------------------------------------
软件是什么,相信很多人都说不清。
作者:
2021/12/10 12:37:41
43楼:
是的,在你的测试里,delphi是比go慢1倍,so what,我看不出会影响什么? 网上发表这些语言比较性能的文章,无非博眼球,技术上压根没有讨论的价值。
----------------------------------------------
软件是什么,相信很多人都说不清。
作者:
2021/12/10 12:58:52
44楼:
就像网上那些所谓大神,吹捧,GIL就是python大神的神笔之作,一个简洁的方案就解决了大问题。 这是水平不高的表现好不!这说明pyhon的核心设计存在问题好不! 所有设计问题都是可计算问题,都是能说出好在哪不好在哪的。 捧捧场说说好话无所谓,但误导了不少初学者;认为,追求简洁就是写代码的终极目标。
----------------------------------------------
软件是什么,相信很多人都说不清。
作者:
hexi (Hexi)
★☆☆☆☆
-
盒子活跃会员
2021/12/12 22:20:55
45楼:
下面这个算法应该速度更快。包括改为多线程,大家可以试试。 procedure TForm1.Button1Click(Sender: TObject); type TUInt64Array=array[0..((1024*1024) div sizeof(UInt64))-1] of UInt64; var FMyTextFile : TFileStream; // just for Text file (plain text) FMyBuffer: array[0..1024*1024-1] of Byte; FMyTotalLines : integer; FMyFileSize : integer; N, i, uN: Integer; U:UInt64; begin FMyFileSize := 0; FMyTotalLines := 0; // FMyTextFile : TFileStream.Create('E:\Data.txt', fmOpenRead); FMyFileSize:=FMyTextFile.Size; while not FMyTextFile. try Reset(FMyTextFile); FMyFileSize := FileSize(FMyTextFile); // while FMyTextFile.Position<FMyTextFile.Size do begin N:=FMyTextFile.Read(FMyBuffer, sizeof(FMyBuffer)); uN:=N div sizeof(UInt64); for i:=0 to uN-1 do begin U:=TUInt64Array(FMyBuffer)[i]; if (U and $FFFF=$0D0A) or (U and $FFFF00=$0D0A00) or (U and $FFFF0000=$0D0A0000) or (U and $FFFF000000=$0D0A000000) or (U and $FFFF00000000=$0D0A00000000) or (U and $FFFF0000000000=$0D0A0000000000) or (U and $FFFF0000000000=$0D0A0000000000)then //AnsiChar //if (U and $FFFFFFFF=$000D000A) or (U and $FFFFFFFF00=$000D000A00) or (U and $FFFFFFFF0000=$000D000A0000) or (U and $FFFFFFFF000000=$000D000A000000) or (U and $FFFFFFFF00000000=$000D000A00000000) then //WideChar Inc(FMyTotalLines); end; if N mod sizeof(UInt64)>0 then begin U:=TUInt64Array(FMyBuffer)[i]; uN:=sizeof(UInt64)- (N mod sizeof(UInt64)); U:=U shr (8*uN); if (U and $FFFF=$0D0A) or (U and $FFFF00=$0D0A00) or (U and $FFFF0000=$0D0A0000) or (U and $FFFF000000=$0D0A000000) or (U and $FFFF00000000=$0D0A00000000) or (U and $FFFF0000000000=$0D0A0000000000) then //AnsiChar //if (U and $FFFFFFFF=$000D000A) or (U and $FFFFFFFF00=$000D000A00) or (U and $FFFFFFFF0000=$000D000A0000) or (U and $FFFFFFFF000000=$000D000A000000) then //WideChar Inc(FMyTotalLines); end; end; finally FMyTextFile.DisposeOf; ShowMessage( { } Format('File size: %d, Total lines: %d', [ { } FMyFileSize, { } FMyTotalLines { } ]) { } ); end; end;
----------------------------------------------
-