1

I use the function uasort in my code several times. I use it to sort my 100-or-so users by a variety of criteria. Users are stored in a multidimensional array. A typical array of users looks a bit like this:

$users => array(
    'username' => // The username key is always lowercase for case-insensitivity.
    array (
      'nick' => 'Username', // Case-ified username, for display purposes.
      'lines' => 8631, // Number of lines spoken.
      'words' => 27343, // Number of words said.
      'chars' => 132596, // Number of characters said.
      'sad' => 24,
      'yell' => 132, // Various mildly-interesting stats.
      'happy' => 4
    )
);

Sorting by the number of lines goes off without a hitch with this:

function top_sort($a, $b) // Sort according to number of lines, in descending order.
{
    return $b['lines'] - $a['lines'];
}
// Elsewhere...
uasort($users, "top_sort");

Execution of this code completes in a fraction of a second.

However, this slightly different code to sort according to the mildly interesting values takes a second (give or take 200ms) to complete for each uasort:

function interesting_sort($a, $b) // Sort according to number of lines, in descending order.
{
global $stattype;
return ($b[$stattype]/$b['lines']) - ($a[$stattype]/$a['lines']);
}
// Elsewhere...
uasort($users, "interesting_sort");

The global variable stattype is set in a foreach loop that iterates through all interesting stats. Removing the loop and global variable, then hardcoding each uasort has no effect. Removing all but one interesting stat after that has no effect. What could be causing such a huge performance hit? The only difference I can see is that the second snippet accesses and extra array value and divides the two. Is something so trivial the source of the problem here?

  • Are you sure all the numeric fields contain numbers rather than strings? If they're strings, PHP will have to parse them each time. – Barmar Aug 22 '14 at 23:18
  • The difference is that you're setting a global var inside of a function. Isn't there a better way? http://stackoverflow.com/questions/5166087/php-global-in-functions – I wrestled a bear once. Aug 22 '14 at 23:33
  • @Adelphia I realize that it's a bit clumsy-looking. I considered (and tried) a few different ways, from hardcoding a new function for each stat and avoiding it entirely to using closures to passing the variable along. None of them seemed to have a noticeable impact on performance, everything varied between .8 and 1.2 seconds per sort. I chose this method for organization purposes. Thanks for that link, though. It was a good read. – Burritosaur Aug 23 '14 at 00:15
  • @Barmar Good idea. I just went through and checked the whole array. Unfortunately, this wasn't it. Everything that's supposed to be an integer is an integer. – Burritosaur Aug 23 '14 at 00:17
  • @Adelphia I don't think there's a way to pass additional parameters through the sorting functions into the comparison function. I don't think there should be a performance implication from using a global variable, it's implemented as a reference to `$GLOBALS['stattype']` – Barmar Aug 23 '14 at 01:22
  • Maybe you should take a look at some of the profiling tools listed here: http://stackoverflow.com/questions/21133/simplest-way-to-profile-a-php-script – Barmar Aug 23 '14 at 01:24
  • @Barmar comment1: Using closures, it's possible to pass another parameter to it. It wasn't as clean as I wanted it to be, so I flipped back to globals after seeing no difference in performance. – Burritosaur Aug 23 '14 at 01:47
  • @Barmar commen2: Thanks a lot for the link. APD and xdebug/kcachegrind look nice. I'll give those a try and edit my question if it comes up with anything helpful. – Burritosaur Aug 23 '14 at 01:49
  • @Barmar I'm a bit confused. For no apparent reason, the code now takes .08 seconds per sort instead of 0.8-1.2 seconds. Still 4 times slower than the first bit of code @.02, but 100 times faster than it was half an hour ago. It's not a measurement error, the lag in page load time was very noticeable, totaling up to 10 second page load times. Now, the page load time is well under a second. The only thing that changed as far as I can tell was that I installed xdebug, but removing it did not slow down page load times. I think it's a problem with the server itself, and thus not a coding problem. – Burritosaur Aug 23 '14 at 23:10

0 Answers0