该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-30
最后修改:2009-05-06
这两天看到有人问为什么好多大公司为什么选择PYTHON,大公司有大公司的考虑,这里只是说说我从实际工作中碰到问题解决后的选择. 呵,呵,我是蛮羡慕RUBY有个很流行的WEB开发框架,也挺有兴趣学习,WEB敏捷开发之道的一二版和programing ruby第2版也买了,可惜因为在的公司进行的都是企业开发,基本上都用JAVA,不能实际应用RAILS,那就当个人兴趣爱好学习了. 去年有次我负责的一个项目需要处理几个文本文件出话单和联通对帐,每个话单文件的处理条数大概是150到200万条,那时候对ruby也有些了解了,脚本语言上手还是挺快的,就用RUBY写了个小程序,花了天把完成任务,记不清当时为什么又用PYTHON来写了个程序来比较,可能是因为这两个脚本语言都比较有名,想多了解比较下的原因吧. 这个程序牵涉到的就是字符串比较和文件读写.(惭愧惭愧,处理时间有差距,但没有我以前说的那么巨大,因为我写的RUBY代码不够高效,有同学改进后的代码提升到3倍以内,详见后帖) 跑程序的机子是台IBM的X60,使用的CPU是T5600,1.8G的,内存是2G,硬盘100G,操作系统是 XP+sp3 , ruby 是一键安装的 1.8.6 吧(今天装的是 1.8.6-27) , python 当时是 2.5.2 今天我用的是(2.6.2),因为准备写这篇帖子,原来的话单文件又比较大,上百M和牵涉到手机号码,就写了个python程序,来生成测试用的话单. 我当时是先写了RUBY,然后按RUBY的写法,又再写了个PYTHON,代码几乎都是一模一样的,也没有考虑什么优化啊编程技巧啊这些,数据需要怎么处理,就用语言提供的数据类型和进行最基本的操作,反正只是个小程序,用了就完了,而且写个脚本程序都要搞很高深的编程技巧,优化技巧,这不就有些为难不是专业人士,就想用脚本程序解决下问题的人了吗? 今天的测试结果: 测试120万条记录,PYTHON跑了40多秒. 200万记录的测试,python跑了55秒. 我平时工作中会经常需要写小程序解决问题,经常牵涉到全省手机号码的处理,一处理就是几十上百万的记录条数,你要说RUBY慢到我不能忍受的地步,也不至于,不过毕竟都喜欢跑得快的程序不是,而且ruby最吸引我的WEB开发,因为工作关系,不能轻易用,平时还是写些小程序处理网络,处理文件用得多些. 所以我最后还是选择了PYTHON,web开发因为工作原因还是用JAVA. 程序代码就贴在下面,压缩包里是所有的相关源文件 执行 MakeTestData.py 指定数字 生成指定数字条数的话单,比如 MakeTestDagta.py 1200000 就生成120万条数据,里面的数据没有任何意义,就是为了达到测试量的数据而已,为了方便,发送和接收数据都设置为指定数据的一半. 然后执行 RunPyTest.bat 或 RunRbTest.bat 进行相关的运行测试,运行完后报告运行时间. 我是希望有人能指点为什么我写的ruby程序比python慢了挺多的,不说又会换回ruby,长长经验也是个好事情嘛... 我刚才又测试了一下,100万条数据,环境如上,跑了10次,结果还是一样,100万条数据的测试结果python 27,要说明下大部分ruby的时间是花在了写结果文件上,看来是IO读写拖了后腿,内存之中的运行应该差不多?(有时间再比较下)不过我这个程序正好碰到了大量的文件读写,我的标题应该改下了,只是有一定的差距... 去掉最后的文件写入,差异也是比较巨大的,PYTHON 10 秒, RUBY 80 秒..测试记录是100万条(去掉最后的文件写入后的代码比较简单,还是有这个差异,要继续寻找答案,呵...) 好象也不算是拖后腿,ruby python 都是用了2/3的时间来写结果文件 我注释掉rb中对format_data的调用,直接赋予'',rb后面的写文件就很快了,那就是字符串操作...? 下面是python处理的代码: 数据处理要求是这样的,分3大步: 1.有一个等待发送状态报告文件来匹配数据的文件,里面包含得有 移动发往联通 wait-status.csv 中第一个字段为3 和 联通发往移动 wait-status.csv 中第一个字段为4 的所有记录 首先读取等待状态报告文件中的数据到哈希表中去,根据第一个字段为3或者4取不同的字段作为key放入到2个不同的(发送和接收)哈希表中 2.然后读取状态报告文件 status.csv 的每一行,根据第一个字段作为KEY尝试去取2个哈希表中的数据, 取得到数据就根据是从哪个哈希表中取出的分别放到2个不同的数组(发送和接收)中去 取不到就丢弃 3.然后把这2个不同的数组中的每条数据转换组合后写到文件中(发送GMO,接收GMT)去就OK了 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-05-03
受益匪浅,thanks
|
|
返回顶楼 | |
发表时间:2009-05-03
稍稍改了改Ruby的几行代码,执行这个测试速度已经比PY的快了,但我相信PY的代码优化后对比Ruby的优化后代码,应该PY还会更快一点的,但决不会很夸张的快
PS:本想优化再对比,但实在耐不下性子看了…… 见过写代码烂的,没见过写代码这么烂的…… 本来不想回复的,但实在没忍住…… ------------- Ruby,PY执行结果还不一样? $ ruby ./RbMakeLost.rb 08-10 ./status.csv ./wait-status.csv ./test/ 时间格式为 09-46-27 正在读取等待状态报告的记录... 读取等待状态报告的记录结束 开始状态报告的比较与分类... 结束状态报告的比较与分类 ./wait-status.csv 处理完毕, 起始时间 09-46-27 结束时间 09-46-27 花费时间为 0.004673 秒 结果如下: 发送给联通成功条数 6 联通发来成功条数 0 [mvp@Arch] [ 9:46AM] [Lost] $ python PyMakeLost.py ./status.csv ./wait-status.csv ./test/ 09-05-03 9:46 正在读取等待状态报告的记录... 读取等待状态报告的记录结束 开始状态报告的比较与分类... 结束状态报告的比较与分类 ./wait-status.csv 文件开始处理于 2009-05-03 09:46:30 结束于 2009-05-03 09:46:30 共花费时间 0 秒 发送给联通成功条数 6 联通发来成功条数 6 |
|
返回顶楼 | |
发表时间:2009-05-03
继续关注此贴,Ruby和Python很难做出一个抉择
|
|
返回顶楼 | |
发表时间:2009-05-03
最后修改:2009-05-03
呵,呵,你的比较只是 6条 数据的处理时间,确实没有什么好比较的,一般也没有谁会在意个0.0几秒,0.几秒,甚至是几秒的差别,我也不会在意,如果你经常只是处理个几十几百条数据,那可能对运行时间没什么感受,自然也就无从比较,无从选择,选择什么只是从个人感觉爱好,从大众推荐,OKOK,你喜欢什么就用什么,没有谁勉强你...
(不过俗话说疾风知劲草,路遥知马力,量变引起质变,不知道你用我提供的脚本生成个100万,200万条数据来测试的结果是怎样的,看到实际结果后你是怎么想的,和你想的相信的是不是有出入?我很好奇...) 至于说到代码烂,你有你的看法,我有我的看法,我写程序也快有10年了,注重运行效率的省级项目也也写个几个,我们省原来的互联短信网关是我写的,每天处理差不多400万的短消息,也没什么问题,精巧高效的代码我很喜欢,也希望我写的都是这样的代码. 不过我前面也说过了,这是个随便写的小程序,用完就算了,我只是从处理需要着手,怎么方便就怎么写,呵,我需要处理的数据就是那样的,就按直观常规的处理思路来写,也不觉得走了什么特别的弯路,写了什么特别恶心的代码,如果你觉得我写的代码很烂,如果你有闲可以的话,请指出很烂的地方,比如指出特别影响效率的语句,或者我的处理思路有哪里严重影响效率,换做你会怎么写?我好在以后写类似程序的时候进行改正,呵.... |
|
返回顶楼 | |
发表时间:2009-05-03
为什么“量变引发质变”? 触发GC!
field01 field02 field03 field04 。。。 field14 tmp_date tmp_date1 tmp_date2 你也使用太多的临时变量了吧,如果使用数组,效率应该可以提升几十倍甚至更多! 还有84行,将x以‘,’为间隔分为数组,最后还是只使用了第一个字符而已!其实使用x[0]就已经OK了,性能应该还会提升几倍左右! 。。。。。。 |
|
返回顶楼 | |
发表时间:2009-05-03
就这代码还不恶心?看看变量的命名,随便写的也不该是这样吧。
|
|
返回顶楼 | |
发表时间:2009-05-03
最后修改:2009-05-04
哦,84行到确实只用了第一个字符,疏忽了,因为后面都要用到SPLIT(',')后的内容的,就顺手写成了SPLIT(','),不过ruby,和python都做了split(',')的语句啊,做了同样的事情,最后程序花的时间大大不同...
呵,一时紧张,都恍惚了,取第一个字符我本来就用的是x[0:1],又没有做无用的SPLIT(','),因为要根据是3还是4取不同的字段做KEY,而每条记录的字段长度不是固定的,所以必须split(), 变量定义多只是为了程序看起来更清楚,望名了意,明白处理的内容而已, field01-14是因为最后的结果文件中有先后顺序的14个字段,变量名称中看到数字确保内容按顺序写入,呵,个人习惯,谁要用只用几个变量做很多事情,那看个人的风格了 用数组会有什么加快?哦,我以为是format_data中使用数组,呵,我觉得用哈希表是合适的,否则光是根据关键字遍历数组查找就够恼火的了,不管你为了效率 还要整什么二分啊更多的查找方法 那些就更要多手多脚去了 我当然知道可能是GC,我也不管什么GC,处理同样多的数据,几乎一样的代码,为什么PYTHON不GC或者是我们没有觉得GC,运行的时间不一样,我就选择快的... |
|
返回顶楼 | |
发表时间:2009-05-03
File.open('test','w') do |x|
10000000.times { x << "联通发来成功条数 " } end ’1000万‘行写入一个文件,在我的破电脑上 Ruby1.8速度为12秒左右 Ruby1.9速度为6秒左右 只能说楼主您的程序可优化能力很强…… ------------------------------ 喜欢PY就学呗……别忽悠比我菜的TX就行…… |
|
返回顶楼 | |
发表时间:2009-05-03
最后修改:2009-05-03
呵,不存在什么忽优,我们是拿真实例子,实际代码说事,又没有空口无凭随便说话,而且我也说了很惊讶程序的结果,希望有人能指点一下,我承认程序应该有优化的余地,但是我的问题是几乎一样的代码(我当时是先写了ruby,然后几乎照着ruby一行行写的python),怎么会有这么巨大的运行差异...
尽说些舍本逐末的评论,举些学术空泛的代码有什么用... |
|
返回顶楼 | |