Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于GO逐行读取大文件的问题,Go为什么耗费时间是PHP7的8倍? #578

Closed
lixuancn opened this issue Dec 18, 2015 · 16 comments

Comments

@lixuancn
Copy link
Contributor

最近写了个脚本,作为学习Go以来第一个实战。但是效果不理想。

一个文件。13G。逐行读取,将读取到的内容按空格切割为数组,取数组中Key=8的值累加。最后得到这个累加的值。

很简单的文件处理程序。Go和PHP都是单线程顺序执行。

虽然PHP是最好的语言,但是Go作为编译型强类型语言,在我的认知里要比PHP快得多才对,就像C的速度是PHP5的1000倍。可现在Go为什么会出现这样的结果?

Go用了300秒,PHP5.6用了200秒,PHP7用了47秒。我是真的不敢相信这就是Google大力推广的Go。我宁愿相信这是我代码的问题

代码:http://www.oschina.net/question/938918_2145778

我周围没什么懂Go的人,问都不知道问谁了。国内社区基本很难获得理想的答案。请赐教!

@lixuancn lixuancn changed the title 关于GO逐行读取大文件的问题,Go为什么耗费时间是PHP3倍? 关于GO逐行读取大文件的问题,Go为什么耗费时间是PHP7的8倍? Dec 18, 2015
@liaosiwei
Copy link

从你的程序上来看你既使用了slice又使用了string,应该会给GC带来不少压力,建议你全部使用slice试试。

@astaxie
Copy link
Owner

astaxie commented Dec 18, 2015

这个题目是我用来培训新人的,可以让大家好好用用Go的pprof。

@lixuancn
Copy link
Contributor Author

@astaxie

1、其实就60行,除了main之外就只有func。
2、其实不用测也知道瓶颈在IO。

@liaosiwei
Copy link

不一定,你还是用pprof跑一下吧

@lixuancn
Copy link
Contributor Author

pprof的top和svg就一行。。

4.57mins of 4.57mins total ( 100%)
flat flat% sum% cum cum%
4.57mins 100% 100% 4.57mins 100%

@lixuancn
Copy link
Contributor Author

@liaosiwei 我之前跑了,就完全没有可用的信息。可能我的方式不对吧

@astaxie
Copy link
Owner

astaxie commented Dec 18, 2015

你是神马系统?还有你怎么跑的?怎么搞pprof的?

@lixuancn
Copy link
Contributor Author

Mac....

在main函数的开头加了:
f, _ := os.Create("profile_file")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()

@astaxie
Copy link
Owner

astaxie commented Dec 21, 2015

Mac系统的cpupprof是有问题的,golang/go#6047

@lixuancn
Copy link
Contributor Author

@astaxie
CentOS 6.2 一样的。都是只有一行。

[lixuan-it@nsctrl1 ~/workspace/gocode/src/letv_dlleak]$ go tool pprof profile_file
Entering interactive mode (type "help" for commands)
(pprof) top5
6.47mins of 6.47mins total ( 100%)
flat flat% sum% cum cum%
6.47mins 100% 100% 6.47mins 100%
(pprof)

@astaxie
Copy link
Owner

astaxie commented Dec 21, 2015

那可能是你的pprof没写对

@wheelcomplex
Copy link

从go profile看,是strings.Fields函数效率不高引起。

@lixuancn
Copy link
Contributor Author

221.181.202.137:80 223.64.60.151 [12/Nov/2015:15:00:05 +0800] "GET /157/2/9/qihu360/0/360.gslb.letv.com/leak/win7/IE9-Windows6.1-KB3100773-x64.msu?crypt=68aa7f2e98550&b=1314&nlh=3072&nlt=45&bf=6000&p2p=1&video_type=msu&termid=0&tss=no&geo=CN-10-0-4&platid=0&splatid=0&its=0&qos=5&fcheck=0&proxy=3719678622,3719678075,467484305&uid=3745528983.rp&keyitem=GOw_33YJAAbXYE-cnQwpfLlv_b2zAkYctFVqe5bsXQpaGNn3T1-vhw..&ntm=1447347600&nkey=255f870a5569bca7254ed170d184a973&nkey2=6a43485b3d99dbb0d58fda89a10d7a28&errc=0&gn=155&buss=61&cips=223.64.60.151&lersrc=ZGxsZWFrLjM2MHNhZmUuY29t&tag=qihu360&cuhost=360.gslb.letv.com&cuid=257407&flw3x=0&sign=coopdown&fext=.msu HTTP/1.1" 206 88925 9.872 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" "-" 221.181.202.137 HIT 99954 bytes=1507328-2113535 - 606208 [12/Nov/2015:14:59:55 +0800] [12/Nov/2015:14:59:55 +0800] [12/Nov/2015:14:59:55 +0800] [12/Nov/2015:14:59:55 +0800] 9.872 9.872 9.872 9.872 error 606208 89280 ok "-" "-"

这只是文件的一行。我需要去提取89280这个数字,也就是按照空格分割后key=8的值。除了按照空格分割,我没有想到别的方式。。。

真心感谢你们的关注@wheelcomplex @anthonyfok。谢谢!

@liaosiwei
Copy link

这种方式没问题,不过我还是建议你不要把slice转成string,string内部实现就是一个byte指针和长度,你把读取的内容转换成string其实做了很多copy工作,直接使用bytes.Field(line),另外如果你确定每一行长度不超过4096,可以用ReadSlice函数,ReadBytes是用ReadSlice实现的,但是多了些copy操作。你这种思路是没问题的。

@wheelcomplex
Copy link

@lixuancn let's stop posting in a closed issue and move to wheelcomplex/wander#1

@kprc
Copy link

kprc commented Jun 2, 2020

这种情况,一定是你代码写的有问题,肯定不是go的问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants