Hi all I have the following function (With the internal stuff cut out) :
/**
* @param int $lastSyncTimeStampLocal
* @return void
*/
protected function compareData(int $lastSyncTimeStampLocal): void
{
$time_start = microtime(true);
foreach ($this->localData as $row) {
$key = array_search($row['uuid'], array_column($this->masterData, 'uuid'));
}
$time_end = microtime(true);
$execution_time = ($time_end - $time_start)/60;
}
This function is to compare 2 sets of data. The problem is the array_search is very slow with large amount of data.
eg if $this->localData and $this->masterData both contains 10000 records then this functions takes approximately 30 seconds to complete. I am wondering if there is an alternative/ any thing I can change to make this a lot faster? Note uuid is a string like 'dkdue29u29dbiyedh92dye'
Thanks for any help
CodePudding user response:
Difficult to test with large result sets, but I hope this works out.
First thing is not to repeat any operation in the loop if you can. So the array_column
call is moved outside the loop.
Rather than using array_search()
, using the values as the keys means you can just do an array reference. BUT using array_flip()
on it's own would mean that you would end up with the last occurrence of rather than the first one. So this code uses array_reverse()
followed by array_flip()
to mean that you end up with a array keyed by the uuid with the value being the position in the array.
(May be worth printing out the $uuids
array to see what I mean by this).
Then inside the loop, you just use a straight forward array access with $uuids[$row['uuid']]
and use ?? -1
which sets -1 when the value is not present.
$uuids = array_flip(array_reverse(array_column($this->masterData, 'uuid')));
foreach ($this->localData as $row) {
$key = $uuids[$row['uuid']] ?? -1;
}