Вы можете получить тот же вывод с циклами for и while:
В то время как:
$i = 0;
while ($i <= 10){
print $i."\n";
$i++;
};
Для:
for ($i = 0; $i <= 10; $i++){
print $i."\n";
}
Но какой из них быстрее?
Вы можете получить тот же вывод с циклами for и while:
В то время как:
$i = 0;
while ($i <= 10){
print $i."\n";
$i++;
};
Для:
for ($i = 0; $i <= 10; $i++){
print $i."\n";
}
Но какой из них быстрее?
Это явно зависит от конкретной реализации интерпретатора/компилятора конкретного языка.
Тем не менее, теоретически любая разумная реализация, вероятно, сможет реализовать ее с точки зрения другой, если бы она была быстрее, поэтому разница должна быть незначительной.
Конечно, я предположил, что while
и for
ведут себя так же, как на C и подобных языках. Вы можете создать язык с совершенно другой семантикой для while
и for
В С# цикл 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");
}
}
Как говорили другие, любой компилятор, заслуживающий своей соли, будет генерировать практически идентичный код. Любая разница в производительности пренебрежимо мала - вы микроуправляете.
Реальный вопрос: что более читаемо? И что цикл for
(по крайней мере, IMHO).
Я считаю, что самый быстрый цикл представляет собой обратный цикл while, например:
var i = myArray.length;
while(i--){
// Do something
}
Если бы это была программа на C, я бы сказал, что нет. Компилятор выдаст точно такой же код. Поскольку это не так, я говорю, что это измеряет. На самом деле, это не о том, какая конструкция цикла быстрее, так как это минимальная сумма экономии времени. Это о том, какая конструкция контура проще поддерживать. В случае, который вы показали, цикл for более уместен, потому что он ожидает, что там будут другие программисты (включая будущее, надеюсь).
Установите итерации цикла в 10 000.
Найдите время в миллисекундах > Run Loop > найдите время в миллисекундах и вычтите первый таймер.
Сделайте это для обоих кодов, что когда-либо имеет самые низкие миллисекунды, они работают быстрее. Вы можете запустить тест несколько раз и выровнять их, чтобы уменьшить вероятность фоновых процессов, влияющих на тест.
Вероятнее всего, вы получите одинаковое время для обоих из них, но мне интересно узнать, всегда ли он немного быстрее.
Они должны быть равны. Цикл for, который вы написали, делает то же самое, что и цикл while: установка $i=0
, печать $i
и увеличение $i
в конце цикла.
Некоторые оптимизирующие компиляторы смогут лучше развернуть цикл с циклом for, но есть вероятность, что если вы делаете что-то, что можно развернуть, компилятор, достаточно умный для его разворота, вероятно, также достаточно умен, чтобы интерпретировать цикл условие вашего цикла while как нечто, что он может развернуть.
Я использовал цикл 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.
В зависимости от языка и, скорее всего, его компилятора, но они должны быть эквивалентны на большинстве языков.
Не важно, что быстрее. Если это имеет значение, сравните его с помощью своего реального кода и убедитесь сами.
Ответы на этот другой вопрос также могут быть полезны: Как написать более эффективный код
Это будет зависеть от реализации языка указанного цикла, компилятора, а что нет.
Большинство компиляторов будет скомпилировать тот же исполняемый код, например, в CIL (.NET), который они определенно делают.
Источник: vcsjones @http://forums.asp.net/t/1041090.aspx
В любом случае, тело цикла - это время, в течение которого время обработки будет потрачено не так, как вы повторяете.
Не является ли "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();
}
Мне было интересно то же самое, поэтому я 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 за цикл
Как для бесконечных циклов for(;;)
цикл лучше, чем while(1)
, так как while
оценивает каждый раз условие, но опять-таки зависит от компилятора.