Какая петля быстрее, пока или для?
Вы можете получить тот же вывод с циклами for и while:
В то время как:
$i = 0;
while ($i <= 10){
print $i."\n";
$i++;
};
Для:
for ($i = 0; $i <= 10; $i++){
print $i."\n";
}
Но какой из них быстрее?
Ответы
Ответ 1
Это явно зависит от конкретной реализации интерпретатора/компилятора конкретного языка.
Тем не менее, теоретически любая разумная реализация, вероятно, сможет реализовать ее с точки зрения другой, если бы она была быстрее, поэтому разница должна быть незначительной.
Конечно, я предположил, что while
и for
ведут себя так же, как на C и подобных языках. Вы можете создать язык с совершенно другой семантикой для while
и for
Ответ 2
В С# цикл For выполняется несколько быстрее.
Для среднего значения цикла около 2,95-3,02 мс.
Цикл While усреднен примерно от 3,05 до 3,37 мс.
Быстрое консольное приложение для подтверждения:
class Program
{
static void Main(string[] args)
{
int max = 1000000000;
Stopwatch stopWatch = new Stopwatch();
if (args.Length == 1 && args[0].ToString() == "While")
{
Console.WriteLine("While Loop: ");
stopWatch.Start();
WhileLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
}
else
{
Console.WriteLine("For Loop: ");
stopWatch.Start();
ForLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
}
}
private static void WhileLoop(int max)
{
int i = 0;
while (i <= max)
{
//Console.WriteLine(i);
i++;
};
}
private static void ForLoop(int max)
{
for (int i = 0; i <= max; i++)
{
//Console.WriteLine(i);
}
}
private static void DisplayElapsedTime(TimeSpan ts)
{
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
}
}
Ответ 3
Как говорили другие, любой компилятор, заслуживающий своей соли, будет генерировать практически идентичный код. Любая разница в производительности пренебрежимо мала - вы микроуправляете.
Реальный вопрос: что более читаемо? И что цикл for
(по крайней мере, IMHO).
Ответ 4
Я считаю, что самый быстрый цикл представляет собой обратный цикл while, например:
var i = myArray.length;
while(i--){
// Do something
}
Ответ 5
Если бы это была программа на C, я бы сказал, что нет. Компилятор выдаст точно такой же код. Поскольку это не так, я говорю, что это измеряет. На самом деле, это не о том, какая конструкция цикла быстрее, так как это минимальная сумма экономии времени. Это о том, какая конструкция контура проще поддерживать. В случае, который вы показали, цикл for более уместен, потому что он ожидает, что там будут другие программисты (включая будущее, надеюсь).
Ответ 6
Установите итерации цикла в 10 000.
Найдите время в миллисекундах > Run Loop > найдите время в миллисекундах и вычтите первый таймер.
Сделайте это для обоих кодов, что когда-либо имеет самые низкие миллисекунды, они работают быстрее. Вы можете запустить тест несколько раз и выровнять их, чтобы уменьшить вероятность фоновых процессов, влияющих на тест.
Вероятнее всего, вы получите одинаковое время для обоих из них, но мне интересно узнать, всегда ли он немного быстрее.
Ответ 7
Они должны быть равны. Цикл for, который вы написали, делает то же самое, что и цикл while: установка $i=0
, печать $i
и увеличение $i
в конце цикла.
Ответ 8
Некоторые оптимизирующие компиляторы смогут лучше развернуть цикл с циклом for, но есть вероятность, что если вы делаете что-то, что можно развернуть, компилятор, достаточно умный для его разворота, вероятно, также достаточно умен, чтобы интерпретировать цикл условие вашего цикла while как нечто, что он может развернуть.
Ответ 9
Я использовал цикл for и while на твердотельной тестовой машине (не выполнялись нестандартные сторонние фоновые процессы). Я запустил for loop
vs while loop
, поскольку он связан с изменением свойства style из 10000 <button>
узлов.
Тест проводился последовательно 10 раз, при этом один запуск выполнялся в течение 1500 миллисекунд перед исполнением:
Вот простой javascript, который я сделал для этой цели
function runPerfTest() {
"use strict";
function perfTest(fn, ns) {
console.time(ns);
fn();
console.timeEnd(ns);
}
var target = document.getElementsByTagName('button');
function whileDisplayNone() {
var x = 0;
while (target.length > x) {
target[x].style.display = 'none';
x++;
}
}
function forLoopDisplayNone() {
for (var i = 0; i < target.length; i++) {
target[i].style.display = 'none';
}
}
function reset() {
for (var i = 0; i < target.length; i++) {
target[i].style.display = 'inline-block';
}
}
perfTest(function() {
whileDisplayNone();
}, 'whileDisplayNone');
reset();
perfTest(function() {
forLoopDisplayNone();
}, 'forLoopDisplayNone');
reset();
};
$(function(){
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
setTimeout(function(){
console.log('cool run');
runPerfTest();
}, 1500);
});
Вот результаты, которые я получил
pen.js:8 whileDisplayNone: 36.987ms
pen.js:8 forLoopDisplayNone: 20.825ms
pen.js:8 whileDisplayNone: 19.072ms
pen.js:8 forLoopDisplayNone: 25.701ms
pen.js:8 whileDisplayNone: 21.534ms
pen.js:8 forLoopDisplayNone: 22.570ms
pen.js:8 whileDisplayNone: 16.339ms
pen.js:8 forLoopDisplayNone: 21.083ms
pen.js:8 whileDisplayNone: 16.971ms
pen.js:8 forLoopDisplayNone: 16.394ms
pen.js:8 whileDisplayNone: 15.734ms
pen.js:8 forLoopDisplayNone: 21.363ms
pen.js:8 whileDisplayNone: 18.682ms
pen.js:8 forLoopDisplayNone: 18.206ms
pen.js:8 whileDisplayNone: 19.371ms
pen.js:8 forLoopDisplayNone: 17.401ms
pen.js:8 whileDisplayNone: 26.123ms
pen.js:8 forLoopDisplayNone: 19.004ms
pen.js:61 cool run
pen.js:8 whileDisplayNone: 20.315ms
pen.js:8 forLoopDisplayNone: 17.462ms
Вот демонстрационная ссылка
Обновление
Ниже приводится отдельный тест, который я провел, который реализует 2 разных письменных факториальных алгоритма 1, используя цикл for, а другой - цикл while.
Вот код:
function runPerfTest() {
"use strict";
function perfTest(fn, ns) {
console.time(ns);
fn();
console.timeEnd(ns);
}
function whileFactorial(num) {
if (num < 0) {
return -1;
}
else if (num === 0) {
return 1;
}
var factl = num;
while (num-- > 2) {
factl *= num;
}
return factl;
}
function forFactorial(num) {
var factl = 1;
for (var cur = 1; cur <= num; cur++) {
factl *= cur;
}
return factl;
}
perfTest(function(){
console.log('Result (100000):'+forFactorial(80));
}, 'forFactorial100');
perfTest(function(){
console.log('Result (100000):'+whileFactorial(80));
}, 'whileFactorial100');
};
(function(){
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
runPerfTest();
console.log('cold run @1500ms timeout:');
setTimeout(runPerfTest, 1500);
})();
И результаты для факториала:
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.280ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.241ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.254ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.254ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.285ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.294ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.181ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.172ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.195ms
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.279ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.185ms
pen.js:55 cold run @1500ms timeout:
pen.js:38 Result (100000):7.156945704626378e+118
pen.js:8 forFactorial100: 0.404ms
pen.js:41 Result (100000):7.15694570462638e+118
pen.js:8 whileFactorial100: 0.314ms
Заключение. Независимо от того, какой тип выборки или тип конкретной задачи проверены, нет четкого выигрыша в отношении производительности между while и циклом. Тестирование выполняется на MacAir с OS X Mavericks на Chrome Evergreen.
Ответ 10
В зависимости от языка и, скорее всего, его компилятора, но они должны быть эквивалентны на большинстве языков.
Ответ 11
Не важно, что быстрее. Если это имеет значение, сравните его с помощью своего реального кода и убедитесь сами.
Ответы на этот другой вопрос также могут быть полезны: Как написать более эффективный код
Ответ 12
Это будет зависеть от реализации языка указанного цикла, компилятора, а что нет.
Большинство компиляторов будет скомпилировать тот же исполняемый код, например, в CIL (.NET), который они определенно делают.
Источник: vcsjones @http://forums.asp.net/t/1041090.aspx
В любом случае, тело цикла - это время, в течение которого время обработки будет потрачено не так, как вы повторяете.
Ответ 13
Не является ли "For Loop" технически "Do While"?
например.
for (int i = 0; i < length; ++i)
{
//Code Here.
}
будет...
int i = 0;
do
{
//Code Here.
} while (++i < length);
Я мог ошибаться, хотя...
Также, когда дело касается циклов. Если вы планируете только извлекать данные и никогда не изменять данные, вы должны использовать foreach. Если вам потребуются фактические индексы по какой-то причине, вам нужно увеличить, чтобы использовать регулярный цикл.
for (Data d : data)
{
d.doSomething();
}
должен быть быстрее, чем...
for (int i = 0; i < data.length; ++i)
{
data[i].doSomething();
}
Ответ 14
Мне было интересно то же самое, поэтому я googled и оказался здесь.
Я сделал небольшой тест на python (чрезвычайно простой), чтобы увидеть, и это то, что я получил:
Для:
def for_func(n = 0):
for n in range(500):
n = n + 1
python -m timeit "import for_func; for_func.for_func()" > for_func.txt
10000 циклов, лучше всего 3: 40,5 мксек за цикл
В то время как:
def while_func(n = 0):
while n < 500:
n = n + 1
python -m timeit "import while_func; while_func.while_func()" > while_func.txt
10000 циклов, лучше всего 3: 45 usec за цикл
Ответ 15
Как для бесконечных циклов for(;;)
цикл лучше, чем while(1)
, так как while
оценивает каждый раз условие, но опять-таки зависит от компилятора.