best/fastest 做法是什么?在 switch 语句的每个 case 中创建相同的循环,或者切换 for 循环的相同 case?
Which is the best/fastest practice? Create the same loop in each case of a switch statement, or to switch the same case of a for loop?
所以我正准备写类似下面的代码
switch ($mode) {
case 'all':
foreach ($sortInfo as $info) $filter[] = array_merge([$info->maincat], $info->subcats);
break;
case 'sub':
foreach ($sortInfo as $info) $filter[] = $info->subcats;
break;
default:
foreach ($sortInfo as $info) $filter[] = [$info->maincat];
break;
}
然后我告诉自己“嘿,如果我把整个 switch 包装在 for 循环中不是更优化吗?”
foreach ($sortInfo as $info) {
switch ($mode) {
case 'all':
$filter[] = array_merge([$info->maincat], $info->subcats);
break;
case 'sub':
$filter[] = $info->subcats;
break;
default:
$filter[] = [$info->maincat];
break;
}
}
但是虽然它在技术上确实节省了一点 (明白了吗?) 文件大小,但循环会在循环的每次迭代中确认 switch 语句中的相同信息。
我认为没有 objective 方法可以确定哪个最快,因为它取决于 $sortinfo
的长度,但由于这是我第一次遇到这种困境,我想了解是否有首选方法,或者您对此有何看法。
基本上,代码和结果是一样的,但我认为第一个会更快,因为它更简单而且 straight-forward。第二个看起来更干净,但它需要 switch-case 并在每次循环时做出决定,这会减慢整个过程。
由于您只会 运行这一次,因此任何性能差异都可以忽略不计。如果必须 运行 数千次,您可以使用固定数据集进行基准测试,但我仍然怀疑您是否会看到超过 +/- 10% 的差异。选择您认为更具可读性的版本。如果你想节省位并且运行宁PHP 8,你可以这样做:
$cats = match($mode) {
'all' => array_merge(
array_column($sortInfo, 'maincat'), ...array_column($sortInfo, 'subcats')
),
'sub' => array_merge(...array_column($sortInfo, 'subcats')),
default => array_column($sortInfo, 'maincat')
};
更新: 根据 OP 的修订,maincat
是单个标量,subcats
是标量数组。由于我们希望在所有模式下都有一个一维数组,因此我们使用 ...
to "dish out" the subcategories into the array_merge
, which gives us a "flat" array. Demo: 3v4l.org/NasiC
这是 227 位与“foreach 切换”中的 338 位对比“foreach 切换”中的 346 位或减少 33%。我发现这种方法 非常 可读并且没有可避免的冗长。
如果你还在 运行nning PHP 7,你可以把这个方法考虑到一个转换中:
switch ($mode) {
case 'all':
$cats = array_merge(
array_column($sortInfo, 'maincat'), ...array_column($sortInfo, 'subcats')
);
break;
case 'sub':
$cats = array_merge(...array_column($sortInfo, 'subcats'));
break;
default:
$cats = array_column($sortInfo, 'maincat');
break;
};
仍然只有 299 个字节。 :) N.B。 match
是我提早升级到 PHP 的主要原因之一 8. 一些菜肴的高级糖,消除了很多样板代码。
好的,看起来提问者不会响应我对示例数据和预期结果的请求。
为了尽量减少重复条件的数量,您可以确定模式是否为“sub”,并简单地收集该列数据(无需任何复杂的处理)。
否则,已知结果中将需要“maincat”数据。唯一要确定的是“subcats”是否应该被推入结果(每行——否则“maincat”和“subcats”关系将被破坏)。
这是直接和简洁的,但它不像 switch()
或 match()
块那样享有最佳的可维护性。如果您不希望扩展代码段的功能,我会在循环前使用一个条件,在循环内使用一个条件。
代码:(没有演示,因为没有提供示例数据)
if ($mode === 'sub') {
$filter = array_column($sortInfo, 'subcats');
} else {
$filter = [];
foreach ($sortInfo as $info) {
$filter[] = [$info->maincat, ...($mode === 'all' ? $info->subcats : [])];
}
}
所以我正准备写类似下面的代码
switch ($mode) {
case 'all':
foreach ($sortInfo as $info) $filter[] = array_merge([$info->maincat], $info->subcats);
break;
case 'sub':
foreach ($sortInfo as $info) $filter[] = $info->subcats;
break;
default:
foreach ($sortInfo as $info) $filter[] = [$info->maincat];
break;
}
然后我告诉自己“嘿,如果我把整个 switch 包装在 for 循环中不是更优化吗?”
foreach ($sortInfo as $info) {
switch ($mode) {
case 'all':
$filter[] = array_merge([$info->maincat], $info->subcats);
break;
case 'sub':
$filter[] = $info->subcats;
break;
default:
$filter[] = [$info->maincat];
break;
}
}
但是虽然它在技术上确实节省了一点 (明白了吗?) 文件大小,但循环会在循环的每次迭代中确认 switch 语句中的相同信息。
我认为没有 objective 方法可以确定哪个最快,因为它取决于 $sortinfo
的长度,但由于这是我第一次遇到这种困境,我想了解是否有首选方法,或者您对此有何看法。
基本上,代码和结果是一样的,但我认为第一个会更快,因为它更简单而且 straight-forward。第二个看起来更干净,但它需要 switch-case 并在每次循环时做出决定,这会减慢整个过程。
由于您只会 运行这一次,因此任何性能差异都可以忽略不计。如果必须 运行 数千次,您可以使用固定数据集进行基准测试,但我仍然怀疑您是否会看到超过 +/- 10% 的差异。选择您认为更具可读性的版本。如果你想节省位并且运行宁PHP 8,你可以这样做:
$cats = match($mode) {
'all' => array_merge(
array_column($sortInfo, 'maincat'), ...array_column($sortInfo, 'subcats')
),
'sub' => array_merge(...array_column($sortInfo, 'subcats')),
default => array_column($sortInfo, 'maincat')
};
更新: 根据 OP 的修订,maincat
是单个标量,subcats
是标量数组。由于我们希望在所有模式下都有一个一维数组,因此我们使用 ...
array_merge
, which gives us a "flat" array. Demo: 3v4l.org/NasiC
这是 227 位与“foreach 切换”中的 338 位对比“foreach 切换”中的 346 位或减少 33%。我发现这种方法 非常 可读并且没有可避免的冗长。
如果你还在 运行nning PHP 7,你可以把这个方法考虑到一个转换中:
switch ($mode) {
case 'all':
$cats = array_merge(
array_column($sortInfo, 'maincat'), ...array_column($sortInfo, 'subcats')
);
break;
case 'sub':
$cats = array_merge(...array_column($sortInfo, 'subcats'));
break;
default:
$cats = array_column($sortInfo, 'maincat');
break;
};
仍然只有 299 个字节。 :) N.B。 match
是我提早升级到 PHP 的主要原因之一 8. 一些菜肴的高级糖,消除了很多样板代码。
好的,看起来提问者不会响应我对示例数据和预期结果的请求。
为了尽量减少重复条件的数量,您可以确定模式是否为“sub”,并简单地收集该列数据(无需任何复杂的处理)。
否则,已知结果中将需要“maincat”数据。唯一要确定的是“subcats”是否应该被推入结果(每行——否则“maincat”和“subcats”关系将被破坏)。
这是直接和简洁的,但它不像 switch()
或 match()
块那样享有最佳的可维护性。如果您不希望扩展代码段的功能,我会在循环前使用一个条件,在循环内使用一个条件。
代码:(没有演示,因为没有提供示例数据)
if ($mode === 'sub') {
$filter = array_column($sortInfo, 'subcats');
} else {
$filter = [];
foreach ($sortInfo as $info) {
$filter[] = [$info->maincat, ...($mode === 'all' ? $info->subcats : [])];
}
}