title: Laravel REST API and high CPU load
body: <p>I am developing a simple RESTful API using Laravel 4.
  I have set a <code>Route</code> that calls a function of my <code>Controller</code> that basically does this:</p>
  
  <ul>
  <li>If information is in the database, pack it in a JSON object and return a response</li>
  <li>Else try to download it (html/xml parsing), store it and finally pack the JSON response and send it. </li>
  </ul>
  
  <p>I have noticed that the CPU load while doing a total of 1700 requests, only 2 at a time together, raises to 70-90%.</p>
  
  <p>I am a complete php and laravel beginner and I've made the API following <a href="http://code.tutsplus.com/tutorials/laravel-4-a-start-at-a-restful-api-updated--net-29785" rel="nofollow">this tutorial</a>, maybe I'm probably doing something wrong or it's just a proof of concept lacking of optimzations. How can I improve this code? (starting function is <code>getGames</code>)
  Do you think the root of all problems is Laravel or I should obtain the same result even changing framework/using raw PHP? </p>
  
  <p><strong>UPDATE1</strong> I also set a file Cache, but the CPU load is still ~50%.</p>
  
  <p><strong>UPDATE2</strong> I set the query rate at two each 500ms and the CPU load lowered at 12%, so I guess this code is missing queue handling or something like this. 
      
  
  <pre><code>class GameController extends BaseController{
      private static $platforms=array(
          "Atari 2600",
          "Commodore 64",
          "Sega Dreamcast",
          "Sega Game Gear",
          "Nintendo Game Boy",
          "Nintendo Game Boy Color",
          "Nintendo Game Boy Advance",
          "Atari Lynx",
          "M.A.M.E.",
          "Sega Mega Drive",
          "Colecovision",
          "Nintendo 64",
          "Nintendo DS",
          "Nintendo Entertainment System (NES)",
          "Neo Geo Pocket",
          "Turbografx 16",
          "Sony PSP",
          "Sony PlayStation",
          "Sega Master System",
          "Super Nintendo (SNES)",
          "Nintendo Virtualboy",
          "Wonderswan");
      private function getDataTGDB($name,$platform){
          $url = 'http://thegamesdb.net/api/GetGame.php?';
          if(null==$name || null==$platform) return NULL;
          $url.='name='.urlencode($name);
          $xml = simplexml_load_file($url);
          $data=new Data;
          $data-&gt;query=$name;
          $resultPlatform = (string)$xml-&gt;Game-&gt;Platform;
  
          $data-&gt;platform=$platform;
          $data-&gt;save();
          foreach($xml-&gt;Game as $entry){
              $games = Game::where('gameid',(string)$entry-&gt;id)-&gt;get();
              if($games-&gt;count()==0){
                  if(strcasecmp($platform , $entry-&gt;Platform)==0 || 
                  (strcasecmp($platform ,"Sega Mega Drive")==0 &amp;&amp; 
                  ($entry-&gt;Platform=="Sega Genesis" || 
                  $entry-&gt;Platform=="Sega 32X" || 
                  $entry-&gt;Platform=="Sega CD"))){
                      $game = new Game;
                      $game-&gt;gameid = (string)$entry-&gt;id;
                      $game-&gt;title = (string)$entry-&gt;GameTitle;
                      $game-&gt;releasedate = (string)$entry-&gt;ReleaseDate;
                      $genres='';
                      if(NULL!=$entry-&gt;Genres-&gt;genre)
                      foreach($entry-&gt;Genres-&gt;genre as $genre){
                          $genres.=$genre.',';
                      }
                      $game-&gt;genres=$genres;
                      unset($genres);
                      $game-&gt;description = (string)$entry-&gt;Overview;
                      foreach($entry-&gt;Images-&gt;boxart as $boxart){
                          if($boxart["side"]=="front"){
                              $game-&gt;bigcoverurl = (string)$boxart;
                              $game-&gt;coverurl = (string) $boxart["thumb"];
                          } continue;
                      }
                      $game-&gt;save();
                      $data-&gt;games()-&gt;attach($game-&gt;id);
                  } 
              }
              else foreach($games as $game){
                  $data-&gt;games()-&gt;attach($game-&gt;id);
              }
          }
          unset($xml);
          unset($url);
          return $this-&gt;printJsonArray($data);
      }
  
      private function getArcadeHits($name){
          $url = "http://www.arcadehits.net/index.php?p=roms&amp;jeu=";
          $url .=urlencode($name);
  
          $html = file_get_html($url);
  
          $data = new Data;
          $data-&gt;query=$name;
          $data-&gt;platform='M.A.M.E.';
          $data-&gt;save();
          $games = Game::where('title',$name)-&gt;get();
          if($games-&gt;count()==0){
              $game=new Game;
              $game-&gt;gameid = -1;
              $title = $html-&gt;find('h4',0)-&gt;plaintext;
              if("Derniers jeux commentés"==$title)
              { 
                  unset($game);
                  return Response::json(array('status'=&gt;'404'),200);
              }
              else{
                  $game-&gt;title=$title;
                  $game-&gt;description="(No description.)";
                  $game-&gt;releasedate=$html-&gt;find('a[href*=yearz]',0)-&gt;plaintext;
                  $game-&gt;genres = $html-&gt;find('a[href*=genre]',0)-&gt;plaintext;
                  $minithumb = $html-&gt;find('img.minithumb',0);
                  $game-&gt;coverurl = $minithumb-&gt;src;
                  $game-&gt;bigcoverurl = str_replace("/thumb/","/jpeg/",$minithumb-&gt;src);
                  $game-&gt;save();
                  $data-&gt;games()-&gt;attach($game-&gt;id);
              }
          }
  
          unset($html);
          unset($url);
          return $this-&gt;printJsonArray($data);
      }
  
      private function printJsonArray($data){
          $games = $data-&gt;games()-&gt;get();
          $array_games = array();
          foreach($games as $game){
              $array_games[]=array(
                  'GameTitle'=&gt;$game-&gt;title,
                  'ReleaseDate'=&gt;$game-&gt;releasedate,
                  'Genres'=&gt;$game-&gt;genres,
                  'Overview'=&gt;$game-&gt;description,
                  'CoverURL'=&gt;$game-&gt;coverurl,
                  'BigCoverURL'=&gt;$game-&gt;bigcoverurl
              );
          }
          $result = Response::json(array(
              'status'=&gt;'200',
              'Game'=&gt;$array_games
              ),200);
          $key = $data-&gt;query.$data-&gt;platform;
          if(!Cache::has($key))
              Cache::put($key,$result,1440);
          return $result;
      }
  
      private static $baseImgUrl = "";
      public function getGames($apikey,$title,$platform){
              $key = $title.$platform;
              if(Cache::has($key)) return Cache::get($key);
          if(!in_array($platform,GameController::$platforms)) return Response::json(array("status"=&gt;"403","message"=&gt;"non valid platform"));
          $datas = Data::where('query',$title)
                  -&gt;where('platform',$platform)
                  -&gt;get();
          //If this query has already been done we return data,otherwise according to $platform
          //we call the proper parser.
          if($datas-&gt;count()==0){
              if("M.A.M.E."==$platform){
                  return $this-&gt;getArcadeHits($title);
              }
              else{
                  return $this-&gt;getDataTGDB($title,$platform);
              }
          } else{
              else return $this-&gt;printJsonArray($datas-&gt;first());
          }
      }
  
  
  }
  ?&gt;
  </code></pre>