The first example that I plan to develop here consists of demonstrating how the timer class that I defined in the first article can be used for benchmarking the performance of a PHP application that fetches the contents of a few simple database rows and prints them on the screen. In this first case, I’m going to perform all this without using HTTP compression when the data is sent to the client. In the second example, all of the data will be compressed when transmitted across the network. Obviously, the timer class will be tasked with timing each of the applications that I mentioned before, indicating which one has the better performance. Also, it should be noted that all the tests will be done using a local host. Thus, the eventual differences that appear between the two examples could be even more significant, if they’re deployed on remote servers. Having clarified this point, here is the complete list of classes that will be used with the first example. Have a look at them, please: // define 'MySQL' class class MySQL{ private $conId; private $host; private $user; private $password; private $database; private $result; const OPTIONS=4; public function __construct($options=array()){ if(count($options)!=self::OPTIONS){ throw new Exception('Invalid number of connection parameters'); } foreach($options as $parameter=>$value){ if(!$value){ throw new Exception('Invalid parameter '.$parameter); } $this->{$parameter}=$value; } $this->connectDB(); } // connect to MySQL private function connectDB(){ if(!$this->conId=mysql_connect($this->host,$this->user,$this->password)){ throw new Exception('Error connecting to the server'); } if(!mysql_select_db($this->database,$this->conId)){ throw new Exception('Error selecting database'); } } // run query public function query($query){ if(!$this->result=mysql_query($query,$this->conId)){ throw new Exception('Error performing query '.$query); } return new Result($this,$this->result); } } // define 'Result' class class Result { private $mysql; private $result; public function __construct($mysql,$result){ $this->mysql=$mysql; $this->result=$result; } // fetch row public function fetchRow(){ return mysql_fetch_assoc($this->result); } // count rows public function countRows(){ if(!$rows=mysql_num_rows($this->result)){ throw new Exception('Error counting rows'); } return $rows; } // count affected rows public function countAffectedRows(){ if(!$rows=mysql_affected_rows($this->mysql->conId)){ throw new Exception('Error counting affected rows'); } return $rows; } // get ID from last-inserted row public function getInsertID(){ if(!$id=mysql_insert_id($this->mysql->conId)){ throw new Exception('Error getting ID'); } return $id; } // seek row public function seekRow($row=0){ if(!is_int($row)||$row<0){ throw new Exception('Invalid result set offset'); } if(!mysql_data_seek($this->result,$row)){ throw new Exception('Error seeking data'); } } } // define 'Timer' class class Timer{ private $elapsedTime; // start timer public function start(){ if(!$this->elapsedTime=$this->getMicrotime()){ throw new Exception('Error obtaining start time!'); } } // stop timer public function stop(){ if(!$this->elapsedTime=round($this->getMicrotime()-$this->elapsedTime,5)){ throw new Exception('Error obtaining stop time!'); } return $this->elapsedTime; } //define private 'getMicrotime()' method private function getMicrotime(){ list($useg,$seg)=explode(' ',microtime()); return ((float)$useg+(float)$seg); } } Well, that’s all for now. As you can see, I defined three simple classes. The first two will be used to connect to MySQL and fetch different result sets. The third one (that is the “Timer” class) will be utilized to roughly time the process of retrieving some rows from a sample database table. Pretty easy, right? Now that you know how all the previous classes will be put to work in a single example, go ahead and read the following section. That's where I’ll show you how to benchmark the retrieval of database rows.
blog comments powered by Disqus |
|
|
|
|
|
|
|