Page 1 of 1

Why should a script run more slowly from distant connection

Posted: Thu Aug 27, 2009 11:31 am
by QuantumTiger
Hi

Just in process of performance testing a website and am scratching my head as to a particular issue. When I access the site from another computer on the same LAN the entire PHP script executes in ~0.016s.

When I access it remotely, it races through the first 9 posts at under 0.003s but then hikes a massive ~0.3s delay on iteration 10.

There is nothing different about that iteration from any other. All it is doing is taking data from an array, calling a function to shorten it and echoing it. The array is pre-populated from a database in the initialisation code. Any thoughts as to what could be causing this gratefully received.

You can see it in action at http://wildlife-photography-blog.com/?perflog=1

I wondered if it could either hitting some kind of caching boundary (although why it donesn't do that when access from LAN I don't know?), or having to do some kind of round-trip handshake with the browser!?

Thanks

Ian
--
http://wildlife-photography-blog.com/

Re: Why should a script run more slowly from distant connection

Posted: Thu Aug 27, 2009 1:16 pm
by requinix
Post some code.

Re: Why should a script run more slowly from distant connection

Posted: Thu Aug 27, 2009 4:26 pm
by QuantumTiger
Ok.

Relevant piece of the template code

Code: Select all

 
     <? Perf("PreMain") ?>
     <? $lc=0 ?>
      <? foreach ($t->res as $item): ?>      
        <div class='entry-head'>
          <a href="<?= $item['siteurl'] ?>"><?=$item['feedname']; ?></a> -
          <?= $item['date']; ?><br />
          <a href="<?= $item['url']; ?>"><?= $item['title']; ?></a>
        </div>
        <div class="entry-body">
          <? if ($t->verbose[0]) echo $item['content'];
              else
                {
                Perf(++$lc . " - PreShorten");
                echo spe::shorten($item['content'],$item['title'],150, $t->verbose[0]);
                Perf("$lc - PostShorten");
                }?>
          <? if(!$t->verbose[0]): ?>
            <a href="<?= $item['url'] ?>">(more...)</a>
          <? endif ?>
          <br /><br />
          <?= $item['catlist'] ?>          
        </div>
      <? endforeach; ?>
     <? Perf("PostMain") ?>
 
The shorten function.

Code: Select all

 
  public function shorten($string, $alternate, $length, $verbose)
  {
  if ($verbose)
    {
    $arr = spe::ReplaceImages($string);
 
    if (!$arr[0]) $data = spe::cleanImgTags($arr[1]);
    else $data = $arr[1];
    return $data;;
    }
  else
    {
    $string = str_replace(">", "> ", $string);
    $short_desc = trim(str_replace(array("\r","\n", "\t"), ' ', strip_tags($string)));
 
    $l = strlen($short_desc);
      
    if ($l==0)
      $desc = $alternate;
    elseif ($l < $length)
      $desc = $short_desc;
    else
      {
      // split on a full stop if we can find one, or a space if not
      $p = strpos($short_desc, ".", $length);
      if ($p===false) $p = strpos($short_desc, " ", $length);
      if ($p===false) $p = 149;
 
      $desc = trim(substr($short_desc, 0, $p+1));
      }
    
    // Send the new description back to the page.
    return $desc;
    }
  }
 
The performance logger

Code: Select all

 
function Perf($loc)
{
global $startTime, $curTime, $pStr;
 
$now = microtime(1);
 
$diff = round($now-$startTime, 3) ;
$diff2 = round($now-$curTime, 3);
 
$pStr .= "<tr><td>$loc</td><td>" . $diff2 . "</td><td>" . $diff . "</td></tr>";
$curTime = $now;
 
return $pStr;
}
 

Re: Why should a script run more slowly from distant connection

Posted: Thu Aug 27, 2009 5:21 pm
by requinix
Could you describe what $t->res is?

Re: Why should a script run more slowly from distant connection

Posted: Thu Aug 27, 2009 5:41 pm
by QuantumTiger
Sure. (Thanks for taking an interest in this btw!)

So $t is an instance of a template wrapper class,

Code: Select all

 
class template
  {
  public $path="";
 
  public function display($template, $content="")
    {
    $t = $this;
    $t->content = $content;
    include( $this->path . $template );
    }
  }
 
and $t->res is the result set from a mysql query

Code: Select all

 
$t->res = $sql->Query("select date, title, url, content, feedname, siteurl, software, catlist
from rssfeed f, fullpost fp where f.feedid = fp.feedid order by fp.date desc
limit $firstItem, $itemsPerPage");
 
The relavent bit of the sql class is

Code: Select all

 
public function Query($sql,$as='indexed')
    {
    $ret = false;
    $this->rowCnt = 0;
 
    if ($this->sqlSess)
      {
      $res=mysql_query($sql, $this->sqlSess);
      $this->rowCnt = mysql_affected_rows($this->sqlSess);
      if ($res)
        {
        if (is_resource($res))
          {
          for ($row=0; $row<$this->rowCnt; $row++ )
            {
            switch ($as)
              {
              case "indexed":
                $resArr[] = mysql_fetch_array($res);
                break; 
              // ***snip rest of case as not relavent***
              }
            }
          if (isset ($resArr))
            $ret = $resArr;
          mysql_free_result($res); 
          }
        else $ret = $res;
        }
      else $ret = mysql_error($this->sqlSess);
      }
    return $ret;
    }
 

Re: Why should a script run more slowly from distant connection

Posted: Fri Aug 28, 2009 3:32 am
by QuantumTiger
Still tearing my hair out on this one.

I temporarily disabled both APC and MySQL caching just to prove they're not a factor. This made almost no difference (note to self check that running APC is actuall worthwhile!).

I've added a parameter to the url to control the number of items (?items=n). With 9 or less items the script doesn't slow down regardless of which page is being served, which seems to prove that it is not a particular row or peice of data which is causing the issue.

http://wildlife-photography-blog.com/?perflog=1&items=9

I tried it from a couple of other internect connections and the magnitude of the delay does seem to vary quite a lot based on ISP, but consistently sits around the same place in the loop (item 10 or 11), which leads me back to my first question about round trip delays. But I still cannot see any reason why the server side script should be influenced by the client to server delay.

edit: Also worth noting. I tested changing the sql to return a short string in place of the long text field 'content', just in case this was the issue. Again - no difference.

Re: Why should a script run more slowly from distant connection

Posted: Fri Aug 28, 2009 11:25 am
by QuantumTiger
Having gone round in circles on this one and done a whole heap of research (google only helps when you know how to frame the right question), I've concluded that this is most likely an output buffering issue.

Using ob_start & ob_end_flush in my template object seems to do the trick.

Code: Select all

 
class template
  {
  public $path="";
 
  public function display($template, $content="")
    {
    $t = $this;
    $t->content = $content;
    ob_start();
    include( $this->path . $template );
    ob_end_flush();
    }
  }