Skip to content

Speed up Arr::unique#52

Merged
SmetDenis merged 1 commit intoJBZoo:masterfrom
Phil-Venter:patch-1
Jun 22, 2024
Merged

Speed up Arr::unique#52
SmetDenis merged 1 commit intoJBZoo:masterfrom
Phil-Venter:patch-1

Conversation

@Phil-Venter
Copy link
Contributor

Benchmark as proof

kv, array_unique              :  462.68 ms [ 332.00 MB] 6666667
kv, foreach isset             :  373.98 ms [ 128.00 MB] 6666667
kv, foreach !isset and        :  431.26 ms [ 128.00 MB] 6666667
kv, foreach !isset &&         :  436.31 ms [ 128.00 MB] 6666667
kv, foreach isset or          :   418.5 ms [ 128.00 MB] 6666667
kv, foreach isset ||          :  416.69 ms [ 128.00 MB] 6666667
kv, foreach                   :  420.97 ms [ 322.00 MB] 6666667
kv, for reverse               :  535.54 ms [ 448.00 MB] 6666667
kv, for reverse isset         :  596.71 ms [ 320.00 MB] 6666667
$max = 10000000;
$arr = range(1, $max, 3); 
$arr2 = range(1, $max, 2); 
$arr = array_values(array_merge($arr, $arr2));

function convert_ts($time)
{
	return round($time / 1e6, 2) . ' ms';
}

function convert_mem(int $bytes, int $decimals = 2): string
{
    $isNegative = $bytes < 0;

    $symbols = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    $bytes = \abs((float)$bytes);
    $exp   = (int)\floor(\log($bytes) / \log(1024));
    $value = ($bytes / (1024 ** \floor($exp)));

    if ($symbols[$exp] === 'B') {
        $decimals = 0;
    }

    return ($isNegative ? '-' : '') . \number_format($value, $decimals, '.', '') . ' ' . $symbols[$exp];
}


$message = 'kv, array_unique';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$temp = array_unique($arr);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, foreach isset';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$temp = [];
foreach ($arr as $key => $val) {
	if (isset($temp[$val])) continue;
	$temp[$val] = $key;
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, foreach !isset and';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$temp = [];
foreach ($arr as $key => $val) {
	!isset($temp[$val]) and $temp[$val] = $key;
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, foreach !isset &&';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$temp = [];
foreach ($arr as $key => $val) {
	!isset($temp[$val]) && $temp[$val] = $key;
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, foreach isset or';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$temp = [];
foreach ($arr as $key => $val) {
	isset($temp[$val]) or $temp[$val] = $key;
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, foreach isset ||';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$temp = [];
foreach ($arr as $key => $val) {
	isset($temp[$val]) || $temp[$val] = $key;
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, foreach';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$temp = [];
foreach ($arr as $key => $val) {
	$temp[$val] = $key;
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, for reverse';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$keys = array_keys($arr);
$temp = [];
for ($i = count($keys) - 1; $i >= 0; $i--) {
	$temp[$arr[$keys[$i]]] = $keys[$i];
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);


$message = 'kv, for reverse isset';
$mem = -memory_get_usage(true);
$time = -hrtime(true);

$keys = array_keys($arr);
$temp = [];
for ($i = count($keys) - 1; $i >= 0; $i--) {
	if (isset($temp[$arr[$keys[$i]]])) continue;
	$temp[$arr[$keys[$i]]] = $keys[$i];
}
$temp = array_flip($temp);

$mem += memory_get_usage(true);
$time += hrtime(true);

echo sprintf('%-30s: %10s [%10s] %s', $message, convert_ts($time), convert_mem($mem), count($temp)) . PHP_EOL;
unset($temp);

@SmetDenis
Copy link
Member

Oh, wow.

This looks really interesting. Let me check it out and I'll be back with some feedback.

@SmetDenis SmetDenis merged commit 15d5e40 into JBZoo:master Jun 22, 2024
@coveralls
Copy link

Coverage Status

coverage: 92.766% (+0.02%) from 92.75%
when pulling 98a542f on Phil-Venter:patch-1
into d8a1733 on JBZoo:master.

@SmetDenis
Copy link
Member

Thank you @Phil-Venter
Looks good. Approved and merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants