Запуск цикла на .DAT-файл в минимальные сроки


Я использую следующий код, чтобы запустить операцию .DAT-файл, который работает нормально. Интернет .файл DAT можно рассматривать как текстовый файл. Моей главной задачей является улучшение исполнения время, когда вам придется запустить на цикл на 25 Мб данных.

$file_name='grid_10min_sunp.dat';

$handle = fopen($file_name, "r");

$lat1=13.86082;
$lan1=100.50509;

 $lat_lon_sunshines = make_sunshine_dict($file_name);


// echo '<pre>';
 //print_r($lat_lon_sunshines);
  //echo count($lat_lon_sunshines);

$closest = 500;
for($c=0;$c<count($lat_lon_sunshines);$c++)
{

//echo $c;  //echo $c;
$lat2=$lat_lon_sunshines[$c]['lat'];
 $lan2=$lat_lon_sunshines[$c]['lan'];
$sunshines=$lat_lon_sunshines[$c]['sunshine'];
//print_r($sunshines);die;
//die;
 $lat_diff = abs(round((float)($lat1), 4)-$lat2);

if ($lat_diff < $closest)
{
    $diff = $lat_diff +  abs(round((float)($lan1), 4)-$lan2); 

     if($diff < $closest)
     {
              $closest = $diff;
            $sunshinesfinal=$sunshines;
     }      
}
$sunshines='';

}
//echo 'sumit';
 print_r($sunshinesfinal);die;

function make_sunshine_dict($file_name)
{

 $sunshines_dict = array();     

  $f = file_get_contents($file_name);

  $handle = fopen($file_name, "r");




  /* for($kkk=0;$kkk<100;$kkk++)
   {    

   $buffer = fgets($handle);*/

  while($buffer = fgets($handle))
  {


 // print_r($buffer);die;
  $tok = strtok($buffer, " \n\t");

   $lat=$tok;

   $latArray[]=$tok;

  //$lat=round(float(values[0]), 4)

 //print_r($buffer);



 // print_r($tok);

   $tok = strtok(" \n\t");

   $months = '';

   $months = array();

    //print_r($tok);die;
   for ($k = 0; $tok !== false; $k+=1) 
   {

   if($k==0)
   {
   $lan=$tok;
   $lanArray[]=$tok;
   }

   if($k!=0)
   {
  /// echo $tok;
        $months[] = $tok ;
         "month $k : ".$months[$k]."<br>";

   }

    $tok = strtok(" \n\t");
    }


    /*echo $lat;
    echo '<br>';
    echo $lang;
    echo '<br>';
    print_r($months);*/


    //$data=new stdClass();
    /*$data->sunshine[]->lat=$lat;
    $data->sunshine[]->lan=$lang;*/

    $data[$kkk]['lat']=$lat;
    $data[$kkk]['lan']=$lan;
    //$sunshines=array();

    foreach($months as $m=>$sunshine)
    {


         $sunshines=array();
          $sumD = 0;

        // $iteration= ($m+1)*30+1;

          $iteration= 31;

          for($n=1;$n<=$iteration;$n++)
          {
              $J = ($m+1)*$n; 



             $P = asin(.39795*cos(.2163108 + 2*atan(.9671396*tan(.00860*($J-186)))));



          $value=(sin(0.8333*pi/180) + sin($lat*pi/180)*sin($P))/(cos($lat*pi/180)*cos($P));

            /* $value ? ($value > 1 and 1) : $value;

             $value ? ($value < -1 and -1): $value;*/


          $D = 24 - ((24/pi) * acos($value));



           $sumD = $sumD + $D;

             }

                $sunshinesdata=(($sumD/30)*(float)($sunshine)*.01);




          //echo '<pre>';

          //print_r($sunshines);die;


           $data[$kkk]['sunshine'][$m]=$sunshinesdata; 

          $sunshines='';
    }
    //echo '<pre>';
    //print_r($data);

    }
 //die;
return $data;

}

Нет никаких проблем в коде выше, за исключением того, что .DAT-файл я использую это 25 Мб, так что вы можете понять, что пройдет еще долгое, долгое время, чтобы запустить его. Как я могу уменьшить время выполнения? Могу ли я использовать индексацию или что?

// echo '<pre>';
 //print_r($lat_lon_sunshines);
  //echo count($lat_lon_sunshines);

$closest = 500;
for($c=0;$c<count($lat_lon_sunshines);$c++)
{

//echo $c;  //echo $c;
$lat2=$lat_lon_sunshines[$c]['lat'];
 $lan2=$lat_lon_sunshines[$c]['lan'];
$sunshines=$lat_lon_sunshines[$c]['sunshine'];
//print_r($sunshines);die;
//die;
 $lat_diff = abs(round((float)($lat1), 4)-$lat2);

if ($lat_diff < $closest)
{
    $diff = $lat_diff +  abs(round((float)($lan1), 4)-$lan2); 

     if($diff < $closest)
     {
              $closest = $diff;
            $sunshinesfinal=$sunshines;
     }      
}
$sunshines='';

}
//echo 'sumit';
 print_r($sunshinesfinal);die;

function make_sunshine_dict($file_name)
{

 $sunshines_dict = array();     

  $f = file_get_contents($file_name);

  $handle = fopen($file_name, "r");




  /* for($kkk=0;$kkk<100;$kkk++)
   {    

   $buffer = fgets($handle);*/

  while($buffer = fgets($handle))
  {


 // print_r($buffer);die;
  $tok = strtok($buffer, " \n\t");

   $lat=$tok;

   $latArray[]=$tok;

  //$lat=round(float(values[0]), 4)

 //print_r($buffer);



 // print_r($tok);

   $tok = strtok(" \n\t");

   $months = '';

   $months = array();

    //print_r($tok);die;
   for ($k = 0; $tok !== false; $k+=1) 
   {

   if($k==0)
   {
   $lan=$tok;
   $lanArray[]=$tok;
   }

   if($k!=0)
   {
  /// echo $tok;
        $months[] = $tok ;
         "month $k : ".$months[$k]."<br>";

   }

    $tok = strtok(" \n\t");
    }


    /*echo $lat;
    echo '<br>';
    echo $lang;
    echo '<br>';
    print_r($months);*/


    //$data=new stdClass();
    /*$data->sunshine[]->lat=$lat;
    $data->sunshine[]->lan=$lang;*/

    $data[$kkk]['lat']=$lat;
    $data[$kkk]['lan']=$lan;
    //$sunshines=array();

    foreach($months as $m=>$sunshine)
    {


         $sunshines=array();
          $sumD = 0;

        // $iteration= ($m+1)*30+1;

          $iteration= 31;

          for($n=1;$n<=$iteration;$n++)
          {
              $J = ($m+1)*$n; 



             $P = asin(.39795*cos(.2163108 + 2*atan(.9671396*tan(.00860*($J-186)))));



          $value=(sin(0.8333*pi/180) + sin($lat*pi/180)*sin($P))/(cos($lat*pi/180)*cos($P));

            /* $value ? ($value > 1 and 1) : $value;

             $value ? ($value < -1 and -1): $value;*/


          $D = 24 - ((24/pi) * acos($value));



           $sumD = $sumD + $D;

             }

                $sunshinesdata=(($sumD/30)*(float)($sunshine)*.01);




          //echo '<pre>';

          //print_r($sunshines);die;


           $data[$kkk]['sunshine'][$m]=$sunshinesdata; 

          $sunshines='';
    }
    //echo '<pre>';
    //print_r($data);

    }
 //die;
return $data;

}


203
2
php
задан 1 октября 2011 в 03:10 Источник Поделиться
Комментарии
1 ответ

Первое, что приходит на ум, заключается в том, что если вы ожидаете много повторяющихся значений можно кэшировать. Так, например, в этот цикл:

for($n=1;$n<=$iteration;$n++) {
$J = ($m+1)*$n;
$P = asin(.39795*cos(.2163108 + 2*atan(.9671396*tan(.00860*($J-186)))));
$value=(sin(0.8333*pi/180) + sin($lat*pi/180)*sin($P))/(cos($lat*pi/180)*cos($P));
$D = 24 - ((24/pi) * acos($value));
$sumD = $sumD + $D;
}

Вы могли бы сделать:

$P_cache = array();
for ($n=1; $n <= $iteration; $n++) {
$J = ($m + 1) * $n;
if (array_key_exists($J, $P_cache)) {
$P = $P_cache[$J];
} else {
$P = asin(...);
...
}
}

Делать это в нескольких местах будет торговля-память по некоторым прирост производительности. Кроме того, поскольку это сайт для проверки кода, я также перечислю несколько пунктов, которые могли бы сделать с некоторым улучшением:


  • Имена переменных должны быть более описательным $J может быть $location_index или что-то более описательное.

  • Использовать функции более принимать все эти сложные тригонометрические расчеты и поставить их в функцию. Это сделает ваш код чище и проще для рассмотрения, и помочь нам дать вам советы по производительности лучше.

2
ответ дан 1 октября 2011 в 10:10 Источник Поделиться