2013-08-13 2 views
0

Я не верю, что это дубликат, я искал его, но на самом деле понятия не имел, что назвать его точно.Почему петли не масштабируются равномерно?

Я хочу знать, почему цикл, который в десять раз больше, чем другой цикл, не требуется в десять раз больше времени для запуска.

Я делал некоторые тесты, чтобы попытаться выяснить, как сделать мой сайт более быстрым и реактивным, поэтому я использовал microtime() до и после функций. На моем веб-сайте я не уверен, как вытащить списки строк таблицы с определенными атрибутами, не пропуская всю таблицу, и я хотел знать, было ли это то, что меня замедлило.

Таким образом, используя следующий цикл:

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 микросекунд? Нужно ли начинать и останавливать цикл или что-то еще?

UPDATE: Чтобы увидеть, был ли это 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 миллисекунд. Итак, мой вопрос все еще стоит. Почему большие петли движутся быстрее? Это не важно, я не планирую весь свой дизайн сайта, основываясь на этом, но мне интересно.

+1

Повторно проверьте свои устройства. Эти дельта времени составляют * миллисекунды *. ('0.332298 с - 0.155500 с = 0.176798 сек = 176.798 миллисекунд') –

+7

Это не имеет ничего общего с циклом. Вы запрашиваете MySQL. Существует 100 факторов. – Brad

+0

если ваш запуск того же запроса, то его кеширование на 'кеше запросов' даже не попал на диск для i/o – DevZer0

ответ

1

Обычно петли будут линейно масштабироваться.

Возможная ошибка: Если вы еще не сделали этого, рассмотреть то, что могло бы произойти, если бы не было записи с идентификатором 900.

Я настоятельно рекомендую использовать MySQL, чтобы сделать вашу работу фильтрации для вас через ИНЕКЕ, а чем сортировка информации таким образом. Это не очень масштабируемо.

Честно говоря, линия

в то время как (! $ 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

ли это поможет ответить на ваш вопрос?

+0

Вы ответили на мой вопрос и многое другое! Я использую циклы, подобные этому, чтобы вытащить продукты и сообщения из базы данных, а на продукты, например, я вытаскиваю продукты по идентификатору продукта, помещаю информацию в шаблон и отображаю ее, а затем повторяю, делая это x раз на страницу. Мне было интересно, как заказать их по цене или дате, но я это откладывал. Как бы я использовал предложения WHERE, чтобы сделать это быстрее, я не совсем понимаю? –

+1

Вы можете использовать операторы SQL для возврата групп строк на основе показателя фильтрации. EG: если вам нужны все записи с идентификаторами в диапазоне 10-100, вы можете написать '$ messagequery = mysqli_query ($ connection," SELECT * FROM users WHERE ID> = 10 AND ID <= 100 ");', который будет верните 91 записи, которые можно повторить с помощью другого цикла. Гибкость фильтрации MySQL намного эффективнее; это лишь базовый пример. Однако это новый вопрос. Это может помочь: http://www.tutorialspoint.com/mysql/mysql-where-clause.htm –

+0

Никогда не осознавал, что могу это сделать! Благодаря! –

1

Если вы действительно заинтересованы в этом, вы можете взглянуть на op-коды, которые создает 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 

Как вы можете увидеть разницу в VS. 1 петле 3000 циклов на самом деле не значительна.

Смежные вопросы