Подтвердить что ты не робот

Какая петля быстрее, пока или для?

Вы можете получить тот же вывод с циклами for и while:

В то время как:

$i = 0;
while ($i <= 10){
  print $i."\n";
  $i++;
};

Для:

for ($i = 0; $i <= 10; $i++){
  print $i."\n";
}

Но какой из них быстрее?

4b9b3361

Ответ 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 оценивает каждый раз условие, но опять-таки зависит от компилятора.