免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5193 | 回复: 12
打印 上一主题 下一主题

一个小测试,不明白为啥python快这么多呢?求解释 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-04 19:40 |只看该作者 |倒序浏览
本帖最后由 PinkOrient 于 2012-11-04 20:41 编辑

说下背景,本人是5+年的Perl老用户,最近对Ruby比较长草,顺便也了解了一下Python.
最近遇到一个需求是分析大量实时生成的csv格式话单,对性能有一定对要求。这种情况下包含了大量的读入字符串并根据分割符做split的操作,做个对比看看3种语言对处理速度如何。

步骤1:写个perl脚本产生50000行每行150个field对csv文件 input_file.txt
  1. pink@pink-desktop:~/_perform$ perl gen_line.pl > input_file.txt
  2. pink@pink-desktop:~/_perform$ cat gen_line.pl
  3. #!/usr/bin/perl
  4. #
  5. $str="string";
  6. for($i=1;$i<150;$i++)
  7. {
  8.     $st=sprintf("string%d", $i);
  9.     $str=$str.",$st";
  10. }
  11. for($i=0;$i<50000;$i++)
  12. {
  13.     print "$str\n";
  14. }
复制代码
步骤2:perl脚本上场,逐行读入,split成数组
  1. $ cat split.pl
  2. #!/usr/bin/perl

  3. open(FF,"input_file.txt");
  4. while(<FF>)
  5. {
  6.     @l=split/,/;
  7.     #print $l[2],"\n";
  8. }
  9. close(FF);
复制代码
time一下看成绩:
  1. pink@pink-desktop:~/_perform$ time ./split.pl

  2. real        0m2.285s
  3. user        0m2.260s
  4. sys        0m0.024s
复制代码
步骤3: ruby脚本上场,做一样的操作
  1. #!/usr/bin/ruby

  2. a=Array.new
  3. f=File.open("input_file.txt","r")
  4. f.each_line do |l|
  5.     a=l.split(/,/)
  6.     #puts a[2]
  7. end
  8. f.close()
复制代码
成绩不是很理想:
  1. pink@pink-desktop:~/_perform$ time ./split.rb

  2. real        0m3.426s
  3. user        0m3.408s
  4. sys        0m0.008s
复制代码
步骤4:python脚本上场,做一样对操作
  1. pink@pink-desktop:~/_perform$ cat split.py
  2. #!/usr/bin/python

  3. fobj=open("input_file.txt","r")
  4. for eachLine in fobj:
  5.     l = eachLine.split(',')
  6.     #print l[2]
  7. fobj.close()
复制代码
成绩让我很意外啊!!
  1. pink@pink-desktop:~/_perform$ time ./split.py

  2. real        0m0.480s
  3. user        0m0.444s
  4. sys        0m0.032s
复制代码
步骤5: 用Ruby 1.9的CSV库,这个据说已经是FasterCSV了
  1. pink@pink-desktop:~/_perform$ cat split_csv.rb
  2. #!/usr/bin/ruby

  3. require "csv"

  4. CSV.foreach("input_file.txt") do |row|
  5.     #puts row[2]
  6. end
复制代码
成绩相当对没法看啊啊啊啊啊....
  1. pink@pink-desktop:~/_perform$ time ./split_csv.rb

  2. real        0m9.381s
  3. user        0m9.337s
  4. sys        0m0.024s
复制代码
以Perl作为基准来比较
Language real percent
Perl 2.285 100%
Ruby 3.426 149.9%
Ruby#CSV 9.381 410.5%
Python 0.480 21%


为什么Python会快这么多?求解释

论坛徽章:
3
CU十二周年纪念徽章
日期:2013-10-24 15:41:34子鼠
日期:2013-12-14 14:57:19射手座
日期:2014-04-25 21:23:23
2 [报告]
发表于 2012-11-04 20:00 |只看该作者
本帖最后由 mcshell 于 2012-11-04 20:01 编辑

我来解释下。。不是split速度慢。。
我举个别人测过的例子:

  1. 一个文件,每行都有18项,各项之间用\t分割,使用时用到了第6项
  2. 1:my @array = split("\t",$_); my $var = $array[6];   测试文件平均用时8.2s
  3. 2. my($var) = (split("\t",$_))[6];  测试平均用时5.1s
  4. 3. my(undef,undef,undef,undef,undef,undef,$var) = split("\t",$_); 平均用时3.53s
  5. 4. my(undef,undef,undef,undef,undef,undef,$var) = split("\t",$_,7);平均用时3.52s
  6. 5. my $var = (split("\t",$_,7))[6]; 平均用时3.53s

复制代码
而你用了效率最低的

论坛徽章:
0
3 [报告]
发表于 2012-11-04 20:21 |只看该作者
本帖最后由 PinkOrient 于 2012-11-04 20:26 编辑

回复 2# mcshell

从Perl内部的纵向比较来看,我完全理解你的代码所产生的效率差异的原因,我的代码是全部field都保存到大数组导致的效率不高。
不过从横向比较来说,这个操作其他几个语言也一样做了,我只是想不通Python用了什么办法让耗时变得这么突出的。

论坛徽章:
0
4 [报告]
发表于 2012-11-04 20:24 |只看该作者
本帖最后由 PinkOrient 于 2012-11-04 20:33 编辑

回复 2# mcshell

根据你的方法优化后的成绩,依然和python有较大对差异啊
  1. pink@pink-desktop:~/_perform$ time ./split.pl

  2. real        0m0.960s
  3. user        0m0.936s
  4. sys        0m0.020s
  5. pink@pink-desktop:~/_perform$ cat split.pl
  6. #!/usr/bin/perl

  7. open(FF,"input_file.txt");
  8. while(<FF>)
  9. {
  10.     $f2=(split/,/)[2];
  11.     #print "$f2\n";
  12. }
  13. close(FF);
复制代码

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
5 [报告]
发表于 2012-11-04 20:25 |只看该作者
让我很意外啊!!

论坛徽章:
0
6 [报告]
发表于 2012-11-04 21:09 |只看该作者
楼主应该试试csv的模块和unpack再来比较,python是封装过的 ,perl看你自己怎么写了。。。。

论坛徽章:
0
7 [报告]
发表于 2012-11-04 21:18 |只看该作者
回复 6# 斯文牛氓


我主要是想比较各个语言提供的标准库,要不直接都调C扩展了。

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
8 [报告]
发表于 2012-11-04 22:28 |只看该作者
python 那个 split 不是正则表达式,要想同一起跑线请用 re.split

论坛徽章:
0
9 [报告]
发表于 2012-11-04 23:03 |只看该作者
楼上说出了真相,python的这个split方法内部根本不是正则表达式。

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
10 [报告]
发表于 2012-11-04 23:43 |只看该作者
关注一下.
一直以为应该是 python慢.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP