免费注册 查看新帖 |

Chinaunix

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

请教:对excel中数值计算的效率优化 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-07-02 08:58 |只看该作者 |倒序浏览
本帖最后由 wand65 于 2014-07-02 08:59 编辑

请教:
今有一份excel表格,里边有sheet 14 页,每页的格式一样,均为 13 列,3201行 (该文件约9M)。
操作如下:对每页第二行开始的第10列求中值,平均值,方差,将结果输出

问题:我的程式可以运行,但运行时间为56s,请大师指点,程式是否可以优化以缩短运行时间,谢谢(如能提供思路或算法十分感谢
  1. #!/usr/bin/perl -w
  2. use strict;
  3. my $time_start=localtime();
  4. print $time_start;
  5. use Spreadsheet::ParseExcel;
  6.     my $parser=Spreadsheet::ParseExcel->new();
  7.     my $workbook =$parser->parse('d:/dick/123.xls');
  8.     if (!defined $workbook)   {
  9.     die $parser->error(),".\n";
  10.     print "nonono" ;
  11.     }
  12.     print  "Tool  Sigma  MiddleValue  AvgValue\n";
  13.    my @tools=qw/K28 K29 K30 K31 K32 K33 K34 K35 K36 K37 K38 K39 K40 K41/;
  14.      foreach my $tool(@tools){
  15.     my $sheet=$workbook->worksheet($tool);
  16.     my @arr=();
  17.     foreach my $i(1..3200){
  18.        my $name=$sheet->get_cell($i,10)->value();
  19.       # print "$name\n";
  20.        push @arr,$name;
  21.        }
  22. #assume there is even number
  23.     @arr=sort@arr;#sorting the values from low to high
  24. my $cout=$#arr+1;
  25. my $sum;
  26. foreach my$j(@arr){
  27.   $sum+=$j; }
  28. my $avg=($sum/$cout);

  29. # middle value
  30. my $mid=$cout/2;
  31. my $mid0=($mid-1);
  32. my $mid_value=($arr[$mid]+$arr[$mid0])/2;

  33. #sigma
  34.   # [1/(n-1)]*{(a[0]-m)^2+(a[2]-m)^2+...+(a[n-1]-m)^2}  ->sigma
  35.   my $square_sum;
  36.   foreach my $va(@arr){
  37.   $square_sum+=($va-$avg)*($va-$avg);
  38. }
  39. my $sigma=sqrt($square_sum/($cout-1));
  40. #print "There are $cout values \n";
  41. # print "$mid,,,$mid0\n";

  42. print  "$tool  \t$sigma\t$mid_value\t$avg\n";

  43. }
  44. my $time_end=localtime();
  45. print $time_end;
复制代码

论坛徽章:
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
2 [报告]
发表于 2014-07-02 17:16 |只看该作者
我不是太确定, 不过, 你sort了 3000个变量的数组, 但我在你的操作中, 并没有看到sort的意义, 最多只是为了一个 mid 值.

其实, 你sum这一步可以省了. 在你push 之前, 就可以把 sum 的值 count 起来了, 这样, push 完了, sum也完了, 少了一次遍历.


论坛徽章:
6
丑牛
日期:2014-03-21 15:42:04子鼠
日期:2014-04-12 11:50:17处女座
日期:2014-09-01 09:25:1115-16赛季CBA联赛之吉林
日期:2015-12-22 14:01:5215-16赛季CBA联赛之广东
日期:2016-03-08 18:49:422016科比退役纪念章
日期:2016-07-06 12:19:55
3 [报告]
发表于 2014-07-02 20:49 |只看该作者
本帖最后由 stanley_tam 于 2014-07-02 20:51 编辑
  1. 你用的模块很耗内存和时间的。。。
  2. my $workbook =$parser->parse('d:/dick/123.xls');
  3. 这一行就会遍历excel里面所有的数据,并全部赋值给$workbook...
  4. 建议使用:
  5. Spreadsheet::ParseExcel::Stream
复制代码

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
4 [报告]
发表于 2014-07-02 21:12 |只看该作者
1,到底是因为 excel 的问题,还是算法的问题。

用一个散列做模拟数据来计算。就知道了。

我感觉这个有点像数据库读取,大部分时间都放在读取上,不如一次性读入,计算完后,一次性写入 excel 。

建议将 excel 的要计算的数据读入一个列表,然后对这个列表进行计算,计算完后,将列表写入原来的表。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP