PHP loop optimization

I have a php method that creates an HTML table with the data it retrieves from a property. My biggest problem is the performance of my application, because I am dealing with a lot of data.

public function getHTML() { $phpObj = json_decode($this->data); // array(object, object, object, ....); $table = "<table><tbody>\n"; if (count($phpObj->query->results->row) > 0) { $row = $phpObj->query->results->row; foreach ($row as $value) { $table .= "<tr>\n"; foreach ($value as $key => $val) { // concerned about loop inside loop $table .= "<td>" . $value->$key . "</td>"; } $table .= "\n</tr>\n"; } $table .= "</tbody></table>"; return $table; } else { return 'HTML table not created.'; } } 

Is there a more efficient way to move through an array and objects without creating a loop inside the loop?

+4
source share
5 answers

Do not concatenate or return a value; pronounce it immediately. Less clean, but performance will be much more interesting, because the lines are immediately output to the output buffer, which is managed more efficiently.

A loop inside a loop is often the best way to move a two-dimensional array.

+4
source

String concatenation is expensive. You can reduce the number of repeated string concatenations using arrays:

 public function getHTML() { $phpObj = json_decode($this->data); if (count($phpObj->query->results->row) > 0) { $rows = array(); foreach ($phpObj->query->results->row as $row) { $cells = array(); $rows[] = "<td>" . implode("</td><td>", $row) . "</td>"; } return "<table><tbody>\n<tr>\n" . implode("\n<tr>\n<tr>\n", $rows) . "\n</tr>\n</tbody></table>"; } else { return 'HTML table not created.'; } } 

You can also use anonymous functions (available since PHP 5.3):

 public function getHTML() { $phpObj = json_decode($this->data); if (count($phpObj->query->results->row) > 0) { return "<table><tbody>\n<tr>\n" . implode("\n<tr>\n<tr>\n", array_map(function($cells) { return "<td>".implode("</td><td>", $cells)."</td>"; }, $phpObj->query->results->row)) . "\n</tr>\n</tbody></table>"; } else { return 'HTML table not created.'; } } 
+2
source

UPDATE Colonel Shrapnel correctly stated that, oddly enough, string concatenation is actually relatively fast in php.

As Vincent said, don't take the bunch of concatenations that are killing you. You have two options to speed up your script:

  • Echo right away.
  • Store your lines in an array and join the array at the end.

Example two:

 <?php $mylines = array(); foreach ($row as $value) { $mylines[] = "<tr>\n"; foreach ($value as $key => $val) { // concerned about loop inside loop $mylines[] = "<td>" . $value->$key . "</td>"; } $mylines[] = "\n</tr>\n"; } return implode('', $mylines); 
+1
source

You can move the HTML building to an external interface and send JSON data to the user through AJAX and javascript.

It may also allow you to send only certain pieces of data (depending on your html layout), so they can be dynamically tested if necessary (e.g. google / bing search).

I know that I did not answer the question directly. This is because the code that you have is probably the fastest that it can do (in PHP) without silly little optimizations that would only make it difficult to read / maintain the code (probably only save a few percent).

EDIT: looking at it again, I'm sure your code is actually just checking data from an external source in JSON. You could probably completely remove this code if the JavaScript script worked with the HTTP message and processed the data. This eliminates the need to run this PHP code.

EDIT 2: after reading your comment that this is a rollback to disable JavaScript, I looked at the code you are currently doing. It seems to translate to implode .

 //declared this functions somewhere function tr_build( $row_value ) { $tablerow .= "<tr>\n"; if( $row_value ) { $tablerow .= "<td>".implode( "</td><td>", $row_value )."</td>"; } $tablerow .= "\n</tr>\n"; return $tablerow; } //this replaces the double loop if( $row ) { $tablerows = "<tr>\n".implode( "\n</tr>\n<tr>\n", array_map( "tr_build", $row ) )."\n</tr>\n" } else { $tablerows = ""; } 
0
source

Why are you so worried?

  $table .= "<tr>\n"; foreach ($value as $key => $val) { // concerned about loop inside loop $table .= "<td>" . $value->$key . "</td>"; } $table .= "\n</tr>\n"; 

You never use $val , so why bother with this loop?

  $table .= "<table><td>"; $table .= implode("</td><td>", array_keys($value)); $table .= "</td></table>"; 
0
source

All Articles