Заявлять array внутри цикла vs о том, что опустошать это в каждом возвращении

Я осведомляюсь о, в C/C ++ ли он лучше объявлять новый array в каждое возвращение циклов:

while(true) {
  char array[255] = "";

  // Hacer algo con el array ...
}

Или опустошать это в каждое возвращение того же самого:

char array[255] = "";

while(true) {
  for(short i = 0; i < sizeof(array); i++) {
    array[i] = 0;
  }

  // Hacer algo con el array...
}

Из-за лучше я отношусь так с перспективы результата (скорости) как хороших практик.

4
задан 09.04.2016, 21:41
4 ответа

В том, что касается хороших практик, лучшее состояло бы в том, чтобы объявлять переменную в самой маленькой / ограниченной области, что ты смог (в этом случае внутри цикла, если он не идет использовать снаружи ни в каком сайте). Он делает код, самый легкий для того, чтобы быть поддержанным (p.e.: ты не должен пересылать 100 линий, чтобы видеть с каким типом инициализировалась переменная x) и в каких-то случаях составитель мог бы применять какой-то метод оптимизации.

Сейчас с точки зрения результата, будешь зависеть в большей степени от составителя (и язык), который ты использовал, и ты был бы должен делать доказательства, чтобы подтверждать, который лучше. Современные составители берутся за то, чтобы оптимизировать произведенный код, а следовательно результат должен бы быть очень похожим (если не равный) в обоих случаях.


... Это была теория, сейчас мы увидим практику. Я создал три случая доказательства (хотя, может быть, не самым научным способом) с циклами, которые повторяют 10 миллионов раз, и ими я выполнил 20 раз, чтобы видеть результаты. Это код:

Я женю 1: заявление внутри цикла

#include <stdio.h>

int main() {
    int x = 0;
    for (x = 0; x < 10000000; x++) {
        char array[255] = "";
        array[0] = (char) (65 + (x%23));
        //printf("%s\n", array);
    }
    return 0;
}

Я женю 2: Заявление вне цикла, опустошенного с циклом for

#include <stdio.h>

int main() {
    int x = 0;
    char array[255];
    for (x = 0; x < 10000000; x++) {
        int y;
        for (y = 0; y < 255; y++) { 
            array[y] = 0;
        }
        array[0] = (char) (65 + (x%23));
        //printf("%s\n", array);
    }
    return 0;
}

Я женю 3: Заявление вне цикла, сбрасывания с memset

#include <stdio.h>
#include <string.h>

int main() {
    char array[255];
    int x = 0;
    for (x = 0; x < 10000000; x++) {
        memset(array,0,255);
        array[0] = (char) (65 + (x%23));
        //printf("%s\n", array);
    }
    return 0;
}

И результаты были (барабанной дробью барабана):

  • Я женю 1 - 0.1587 секунд
  • Я женю 2 - 6.1470 секунды
  • Я женю 3 - 0.1413 секунд

Что немного ********, потому что он бросает из-за земли каждую часть теории, которую я поместил наверху. Для первого и третьего случая да он был бы выполнен, но не для второго случая (конечно я сделал что-то плохим... или у меня есть самый худший составитель мира, который также достаточно возможный).

5
ответ дан 24.11.2019, 14:37
  • 1
    Это ответ, что я quer и # 237; чтобы давать, 100 % договора. Твоя теория верная, но цикл внутри другого цикла всегда быть и # 225; м и # 225; s медленный, memset будь осуществлен ensam и это специфический случай наполнения всего с 0, если это condici и # 243; n очень специфическая составителя, чтобы производить c и # 243; я говорю очень оптимизированный. – JuanK 11.04.2016, 15:17
  • 2
    Случай 2 - м и # 225; s медленный просто, потому что он повторяет 250.000.0000 из раз, пока другие повторяют просто 1.000.000 из раз. Эти различия времени не имеют ничего общего с ubicaci и # 243; n declaraci и # 243; n. – jgomo3 11.04.2016, 15:55
  • 3
    #161; Превосходный ответ, большое спасибо! Я записываюсь memset для будущих ссылок, хорошей заметки. – Hewbot 11.04.2016, 19:47

Хорошие практики показывают, что рекомендуемое состоит в том, чтобы область переменных была возможным минимумом. Эта рекомендация стремится к тому, чтобы предотвратить повторное применение переменных для различных концов.

В условиях результата кажется очевидным приходить к заключению о том, что вынуждать к программе размещать и инициализировать X байт памяти в каждом повторении цикла будут являться более дорогим, который размещать однажды и инициализировать в каждом повторении цикла.

Итак, результат обычно является спорной темой. В примере, который ты предлагаешь: Возможно считать важным время, которое будет использовать систему, чтобы размещать 255 байт в каждой договоренности? Конечный respueta зависит от обязательных условий алгоритма. Если, например, эта функция будет опаздывать второй способ и только будет работать, когда пользователь нажимает на кнопку, возможно считаться спокойно, что время презренное..., если взамен время - критическая единица и оставшаяся часть алгоритма супер оптимизирована вещь, изменись.

Моя рекомендация состоит в том, чтобы сначала ты беспокоился, создания читабельного кода и, однажды закончено, comrpuebes, если необходимо оптимизировать это, или если, с которым он имеет, он выполняет спецификации.

Конечно, для incializar память ты можешь использовать memset вместо того, чтобы создавать твой собственный цикл.

1
ответ дан 24.11.2019, 14:37

Я понимаю, что комплексность будет линейной и процесс резерва памяти и равной инициализации дорогого или с ценами, казавшимися каждым возвращением цикла; но он состоит dífícil в том, чтобы оценивать, так как составитель может принимать решения, чтобы оптимизировать код.

Кажется, что ты напротив случая недозрелой оптимизации (early optimization на английском):

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

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

Изданный:

С другой стороны, завись от использования, которое ты будешь давать ему в array, ты можешь нарушать шаг инициализации:

while(true) {
    char array[255];

    // Hacer algo con el array ...
}

Если ты не распределишь стоимость array, этот не будет инициализироваться в 0 и следовательно, это будет минус один процесс, который будет нужно делать в каждом возвращении цикла (не плати за то, что ты не используешь, это начало C ++). Это будет полезным, если первое, что ты делаешь с array он состоит в том, чтобы писать в, так что Ваша предварительная информация не является значимой... даже это мог бы быть мотив для того, чтобы составитель повторно использовал место array в каждом возвращении вместо того, чтобы это создавать снова.

1
ответ дан 24.11.2019, 14:37
  • 1
    char array[255] он не кажется точно array изменчивой длины. – eferion 11.04.2016, 10:46
  • 2
    С другой стороны, для договоренностей установленной длины, поскольку это случай, быть и # 237; в рекомендуемый использовать std::array вместо std::vector – eferion 11.04.2016, 11:01
  • 3
    Это не ALV, я написал слишком много r и # 225; я прошу. И если, std::array быть и # 237; в elecci и # 243; n правильная, asum и # 237; что был ALV поэтому suger и # 237; std::vector. – PaperBirdMaster 11.04.2016, 11:22

Нужно иметь в виду, что создавать локальный array в функцию - тривиально для составителей в большинстве случаев, так как говорится о простой настройке размера батарейки.

Во многой архитектуре, налаживать размер батарейки занимает очень мало инструкций в машинном коде, и не соглашается в memória. Простой факт 'отлаживания' array с array[0] = 0 смоги подразумевать этот устрашающий доступ в memória (он зависит от использования array внутри цикла, так что последние доступы способствуют тому, чтобы 'array [0]' он был внутри линий кэша процессора).

Любопытная стоимость, полученная, отложив array посредством memset() он происходит возможно от составителя. gcc, например, помоги memset() посредством произведенного машинного кода inline, не реализовывая никакого призыва к какой-либо реальной функции. Это, вместе с его собственной оптимизацией, будет ответственное лицо за такую неожиданную скорость.

Сравнивая это со случаем array[0]=0, здесь, если, который мы вынуждаем составителя, который должен производить код; из-за многого, что были оптимизированы, составителей еще не умеют программировать одинокие они ;-)

Я распознаю, что скорость, использовав memset() он застал меня.

0
ответ дан 24.11.2019, 14:37

Теги

Похожие вопросы