Chinaunix

标题: 请教:对excel中数值计算的效率优化 [打印本页]

作者: wand65    时间: 2014-07-02 08:58
标题: 请教:对excel中数值计算的效率优化
本帖最后由 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;
复制代码

作者: q1208c    时间: 2014-07-02 17:16
我不是太确定, 不过, 你sort了 3000个变量的数组, 但我在你的操作中, 并没有看到sort的意义, 最多只是为了一个 mid 值.

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



作者: stanley_tam    时间: 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
复制代码

作者: 104359176    时间: 2014-07-02 21:12
1,到底是因为 excel 的问题,还是算法的问题。

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

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

建议将 excel 的要计算的数据读入一个列表,然后对这个列表进行计算,计算完后,将列表写入原来的表。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2