0

我不相信这是重复的,我一直在寻找它,但真的不知道该怎么称呼它。

我想知道为什么一个比另一个循环大十倍的循环不需要十倍的时间来运行。

我正在做一些测试,试图弄清楚如何让我的网站更快、更具反应性,所以我使用microtime()了 before 和 after 功能。在我的网站上,我不确定如何在不遍历整个表格的情况下提取具有某些属性的表格行列表,我想知道这是否是让我慢下来的原因。

所以使用以下循环:

echo microtime(), "<br>";
echo microtime(), "<br>";
session_start();
$connection = mysqli_connect("localhost", "root", "", "") or die(mysqli_connection_error());; 
echo microtime(), "<br>";
echo microtime(), "<br>";
$x=1000;
$messagequery = mysqli_query($connection, "SELECT * FROM users WHERE ID='$x'");
while(!$messagequery or mysqli_num_rows($messagequery) == 0) {
    echo('a');
    $x--;
    $messagequery = mysqli_query($connection, "SELECT * FROM users WHERE ID='$x'");
    }
echo "<br>";
echo microtime(), "<br>";
echo microtime(), "<br>";

我得到以下输出和类似的输出:

0.14463300 1376367329
0.14464400 1376367329
0.15548900 1376367330
0.15550000 1376367330 < these two
[a's omitted, for readability]
0.33229800 1376367330 < these two
0.33230700 1376367330

~18-20 微秒,还不错,没有人会注意到。所以我想知道随着我的网站的发展会发生什么。如果我有 10 倍 (10,000) 个表行来搜索会发生什么?

0.11086600 1376367692
0.11087600 1376367692
0.11582100 1376367693
0.11583600 1376367693
[lots of a's]
0.96294500 1376367694
0.96295500 1376367694

~83-88 微秒。为什么不是 180-200 微秒?启动和停止循环是否需要时间?

更新:要查看是否是 mySQL 添加变量,我在没有 mySQL 的情况下对其进行了测试:

echo microtime(), "<br>";
echo microtime(), "<br>";
session_start();
$connection = mysqli_connect("localhost", "root", "W2072a", "triiline1") or die(mysqli_connection_error());; 
echo microtime(), "<br>";
echo microtime(), "<br>";
$x=1000000;
while($x > 10) {
    echo('a');
    $x--;
    }
echo "<br>";
echo microtime(), "<br>";
echo microtime(), "<br>";

现在看来,一百万,它需要〜100毫秒(对吗?),一千万,它需要〜480毫秒。所以,我的问题仍然存在。为什么较大的循环移动得更快?这并不重要,我不会基于此计划我的整个网站设计,但我很感兴趣。

4

2 回答 2

1

通常,循环将线性缩放。

可能的错误:如果您还没有这样做,请考虑如果没有 id 为 900 的记录会发生什么。

我强烈建议使用 MySQL 通过 WHERE 子句为您完成过滤工作,而不是通过这种方式对信息进行排序。它不是真正可扩展的。

坦白说,线

while(!$messagequery 或 mysqli_num_rows($messagequery) == 0) {

对我来说没有意义。 $messagequery如果发生故障,将是错误的,并且您希望循环运行只要mysqli_num_rows($messagequery)不等于零,我认为。但是,这不是上面代码的作用。

如果mysqli_num_rows($messagequery)等于零,则循环将继续。

如果mysqli_num_rows($messagequery)不等于零,则循环将停止。

查看运算符优先级:http: //php.net/manual/en/language.operators.precedence.php

这有助于回答你的问题吗?

于 2013-08-13T04:49:17.497 回答
1

如果你真的对此感兴趣,你可以看看 PHP 创建的操作码。Vulcan Logic Disassembler (VLD)可能会帮助您解决这个问题。

但是,如果您只对网站速度感兴趣,这应该不是您的问题。您不会仅仅因为循环本身而获得速度优势/缺点,而是因为它们实际循环的事物(MySQL 查询,数组,......)。

比较这个小测试脚本:

<pre>
<?php

$small_loop = 3000;
$big_loop = $small_loop*$small_loop;
$start = microtime(true);

// Big loop
for ($i = 0; $i < $big_loop; $i++) {
    ; // do nothing
}
echo "Big loop took " . (microtime(true) - $start) . " seconds\n";

$start = microtime(true);
// Small loops
for ($i = 0; $i < $small_loop; $i++) {
    for ($j = 0; $j < $small_loop; $j++) {
        ;
    }
}
echo"Small loops took " . (microtime(true) - $start) . " seconds\n";
?>
</pre>

我的输出是:

Big loop took 0.59838700294495 seconds
Small loops took 0.592453956604 seconds

正如您所见,1 次循环与 3000 次循环的差异并不显着。

于 2013-08-13T05:04:20.240 回答