这是假设的代码,假设我有以下内容:
假设我有一个数组,它在这个示例问题中有很多数据,整数,但是它可以在if语句中以某种方式对任何类型的数据进行排序。
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,...,9,9,9);
假设我有一个包含许多if else if语句的for循环,那些可以有任何做某事的标准。
for($i=0; i<count($a); i++) {
// these if statements can be anything and may or may not be related with $a
if($a[$i] == 0 && $i < 10) {
// do something
}
else if($a[$i] == 1 && $i < 20) {
// do something
}
else if($a[$i] == 2) {
// do something
}
else if($a[$i] == 3) {
// do something
}
// and so on
}
现在的问题是,在第一次if语句迭代完成后,它从未被使用过。一旦for循环开始使用下一个if语句,就不需要再次评估前面的if语句。它可以使用第一个if语句n次等等。
有没有办法优化它,所以它不必遍历所有以前的if else if语句,因为它循环数据?记住,数据可以是任何东西,if语句可以是各种条件。
是否存在一种范式转换,我没有看到,这应该如何编码以提供最佳性能?
答案 0 :(得分:1)
您可以利用call_user_func_array
。您需要构建一个存储方法的类来调用以执行语句。考虑这样一个类:
class MyStatements {
public function If0($a, $i) {
if($a[$i] == 0 && $i < 10) {
// do something
}
}
public function If1($a, $i) {
if($a[$i] == 1 && $i < 20) {
// do something
}
}
}
然后你可以做这样的事情:
$stmts = new MyStatements();
for($i = 0; i < count($a); i++) {
call_user_func_array(array($stmts, 'If' . strval($i)), array($a, $i));
}
答案 1 :(得分:0)
将for语句分解为多个for语句。对于您的示例代码:
for($i=0; i<10; i++) {
if($a[$i] == 0) {
//do something
}
}
for($i=0; i<20; i++) {
if($a[$i] == 1) {
//do something
}
}
for($i=0; $i<count($a); $i++) {
if($a[$i] == 2) {
// do something
}
else if($a[$i] == 3) {
// do something
}
}
//etc...
答案 2 :(得分:0)
PHP使用一种称为“短路评估”的东西,就像许多其他现代语言一样。这意味着一旦布尔表达式被确定为真或假,表达式的其余部分将不会被评估。
因此,您可以引入新的布尔值(可能是它们的数组)来跟踪是否已经执行了一段代码,如果已经执行了,则将其设置为false。然后使用此布尔值作为“if”表达式中的第一个条件。 PHP将识别此值的值设置为false,并忽略该子句的其余部分。这是一条非常简单的路线,可以保持您的代码大部分按现在的方式构建。
答案 3 :(得分:0)
我认为你正在转动你的车轮。
如果你有大量数据,那么很可能是数据源慢而不是服务器端计算。
如果您执行任何操作,则应将数据分解为块并一次运行部分。如果您注意到服务器上的加载时间较慢或负载较差,则只需执行此操作。
异步连接允许您轻松地执行此操作,使用ajax可以连接到服务器,提取有限的数据块,处理它,然后在客户端浏览器中显示后,运行下一个块。无论何时使用查询大量数据的网站(即:facebook),都可以这样做。
但同样,不要过度思考这一点。你真的不需要让你的程序更复杂。如果你真的想要一个金星,你可以创建一个面向对象的类,为你处理所有这些,但我不会深入研究。
答案 4 :(得分:0)
如果您使用的是PHP 5.3+,则可以使用anonymous functions。
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
$dispatch = array(
0=>function() { echo "0"; },
1=>function() { echo "1"; },
2=>function() { echo "2"; },
3=>function() { echo "3"; },
9=>function() { echo "9"; }
);
foreach ($a as $i)
{
$dispatch[$i]();
}
在PHP 5.3之前,您必须使用映射来表示函数名称,但底部也适用于PHP 5.3+。
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
function foo0() { echo "0"; }
function foo1() { echo "1"; }
function foo2() { echo "2"; }
function foo3() { echo "3"; }
function foo9() { echo "9"; }
$dispatch = array(
0=>"foo0",
1=>"foo1",
2=>"foo2",
3=>"foo3",
9=>"foo9"
);
foreach ($a as $i)
{
$dispatch[$i]();
}
上面的代码更快,但效率不高。要提高性能,您必须在$ dispatch数组中删除键查找,并在每次$ a [#]的值更改时向前移动。这假设您的$ dispatch数组与输入数组匹配。如果$ dispatch数组非常大,你只会获得性能提升。
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
function foo0() { echo "0"; }
function foo1() { echo "1"; }
function foo2() { echo "2"; }
function foo3() { echo "3"; }
function foo9() { echo "9"; }
$dispatch = array(
0=>"foo0",
1=>"foo1",
2=>"foo2",
3=>"foo3",
9=>"foo9"
);
reset($dispatch);
$foo = (string)current($dispatch);
$last = 0;
foreach ($a as $i)
{
$foo();
if($i != $last)
{
$foo = (string)next($dispatch);
$last = $i;
}
}
这应该尽可能高效。
答案 5 :(得分:0)
我不确定这与The Solution有什么不同,但我想我会把它扔出去。
function func1 () {
echo "hi\n";
}
function func2 () {
echo "bye\n";
}
$functionList = array (
0 => "func1",
1 => "func2"
);
$a = array(0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,9,9,9);
$len = count($a);
for($i = 0; $i < $len; $i++) {
if (isset($functionList[$i])) {
call_user_func($functionList[$i]);
}
}
我明确设置了$functionList
的键,因为OP表示它们并不总是数字。也许前2-3个作业可以包装成一个类。
答案 6 :(得分:0)
这个详细的解决方案将阻止任何if
条件在评估为false后运行,并且不会多次迭代相同的$i
值,除非它转换到下一个循环。
for($i=0; i<count($a); i++) {
if($firstCondition) {
//do something
} else {
break;
}
}
for($i; i<count($a); i++) {
if($secondCondition) {
//do something
} else {
break;
}
}