Page 1 of 1

Optimizing simple function??

Posted: Thu Apr 13, 2006 4:07 pm
by Terriator
Hey, I have following code:

Code: Select all

function num_users(){
  //Current Time
  $time = time()-300;
  //count database rows
  $usernum = doquery("SELECT * FROM users WHERE update_time > $time");
  $num = mysql_num_rows($usernum);
  //Post
  echo"<b><i>$num Users Online: </i></b>";
  while($row = mysql_fetch_assoc($usernum)){
         if($row['rank']=="Academy Student"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#808080' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Genin"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#666699' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Chuunin"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#333399' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Jounin"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#000080' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Special Jounin"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#333300' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Lower Outlaw"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#FF0000' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Higher Outlaw"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#993300' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Special Outlaw"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#800000' size='-1'>$row[username]</font></a> - ";}
         if($row['rank']=="Kage"){
           echo"<a href='member_list.php?page=userprofile&name=$row[username]'><font color='#000000' size='-1'>$row[username]</font></a> - ";}
  }
  echo"<br /><br /><font size='-1'><b><i>Classes:</i></b></font>
       <font color='#808080' size='-2'>Academy Students</font> |
       <font color='#666699' size='-2'>Genin</font> |
       <font color='#333399' size='-2'>Chuunin</font> |
       <font color='#000080' size='-2'>Jounin</font> |
       <font color='#333300' size='-2'>Special Jounin</font> |||
       <font color='#FF0000' size='-2'>Lower Outlaw</font> |
       <font color='#993300' size='-2'>Higher Outlaw</font> |
       <font color='#800000' size='-2'>Special Outlaw</font> ";
}
When having hundreads of users online this is rather slow, is there a quicker way to do this?

Posted: Thu Apr 13, 2006 4:18 pm
by feyd
Use an array, or make the database do it.

Posted: Thu Apr 13, 2006 4:20 pm
by Terriator
Example please??

Posted: Thu Apr 13, 2006 4:22 pm
by feyd
You can create a map between the names and colors to use, other than that, all the data is the same.

Posted: Thu Apr 13, 2006 4:23 pm
by Oren
First of all, you don't need to select all columns to count the number of online users - you can do it like this:

Code: Select all

$num = mysql_num_rows(doquery("SELECT update_time FROM users WHERE update_time > $time"));
And for the long if's list - try to use the switch structure as it is a little bit faster according to http://www.blueshoes.org/phpBench.php

Posted: Thu Apr 13, 2006 4:51 pm
by Terriator
Heh, I guess I'm just not experienced enough to understand that feyd - How would I do that array thing?

Posted: Thu Apr 13, 2006 4:57 pm
by feyd

Code: Select all

$colors['Academy Student'] = '808080';
$colors['Genin'] = '666699';
for example.

Posted: Fri Apr 14, 2006 9:30 am
by HubGoblin
HTML generation is what slows down your application. Use templates to speed up.

Posted: Fri Apr 14, 2006 9:34 am
by malcolmboston
HubGoblin wrote:HTML generation is what slows down your application. Use templates to speed up.
an extra templating layer would slow down the site, PHP is basically designed to output PHP, hence why its a web language

Posted: Sat Apr 15, 2006 4:47 am
by Terriator
I still don't get the array / map thing =/ .. Though I've tried.. Could you go more into detail??

Posted: Sat Apr 15, 2006 9:06 am
by printf
You could replace all that, and put in your query, MySQL will be faster, even using multi IF(s). But this depends on your database version, because CONCAT() will revert to utf8_general_ci, which will not match what most people use for their default collation set (latin1_swedish_ci). But you can use coalesce() so you avoid the (#1271 - Illegal mix of collations for operation 'concat'), when using IF() inside CONCAT()!

Here is the query...

Code: Select all

$sql = "SELECT CONCAT(\"<a href='member_list.php?page=userprofile&name=\", username, \"'><font color='#\", IF(rank='Academy Student', '808080',IF(rank='Genin', '666699', IF(rank='Chuunin', '333399', IF(rank='Jounin', '000080', IF(rank='Special Jounin', '333300', IF(rank='Lower Outlaw', 'FF0000', IF(rank='Higher Outlaw', '993300', IF(rank='Special Outlaw', '800000', '000000')))))))),\"' size='-1'>\", username, \"</font></a>\" ) AS link FROM users WHERE update_time > " . $time;

$result = mysql_query ( $sql );

if ( mysql_num_rows ( $result ) > 0 )
{
	$data = array ();

	while ( $row = mysql_fetch_assoc ( $result ) )
	{
		$data[] = $row['link'];
	}

	echo implode ( ' - ', $data );
}
printf!