Страницы

Поиск по вопросам

понедельник, 1 апреля 2019 г.

Какой из вариантов циклов быстрее?

Есть блоки кода вычислений блок1, блок2, блок3, блок4,...блок 10, скажем. Скажите, как поступить при использовании их в цикле: for (i = 0; i <= n; i++) { блок1; блок2; блок3; блок4; ... блок10; } Или же так оптимально: for (i = 0; i <= n; i++) { блок1; }
for (i = 0; i <= n; i++) { блок2; }
.............
for (i = 0; i <= n; i++) { блок10; } Можете объяснить почему? Мне лично кажется, что первый вариант быстрый и правильный.


Ответ

Ответ скорее не ТС, а @IronVbuf. Начало развернутого комментирования его ответа. Копия моего комментария: @IronVbif, рассуждения красивые. Время позднее, не хочу (сейчас) все разбирать. Если правильно понял, в пунктах 4, 5 и 6 Вы склоняетесь к тому, что несколько маленьких циклов (особенно если их тела маленькие) будут производительней одного. Практический замер (gcc -O3 MinGW (32-bit) Windows 7 64-bit I5-2500 3.3GHz) показал обратное (причем аж в 3 раза для 6 циклов и 10^9 повторов маленьких вычислений (преобразование int->double, double умножение и сложение) Примерчик (нисколько не претендует на полноту, 5 минут на коленке). gcc -O3 MinGW (32-bit) Windows 7 64-bit I5-2500 3.3GHz #include
#define incvar(x,y) {x = x + i*y;} main (int ac, char *av[]) { double a = 0, b = 0, c = 0, d = 0, e = 0, f = 0; int i; if (av[1]) { printf ("one loop
"); for (i = 0; i < 1000000000; i++) { incvar(a,1.234); incvar(b,7.234); incvar(c,11.234); incvar(d,111.234); incvar(e,51.234); incvar(f,21.234); } } else { printf ("six loops
"); for (i = 0; i < 1000000000; i++) incvar(a,1.234); for (i = 0; i < 1000000000; i++) incvar(b,7.234); for (i = 0; i < 1000000000; i++) incvar(c,11.234); for (i = 0; i < 1000000000; i++) incvar(d,111.234); for (i = 0; i < 1000000000; i++) incvar(e,51.234); for (i = 0; i < 1000000000; i++) incvar(f,21.234); }
printf ("%e %e %e %e %e %e
",a,b,c,d,e,f); }
c:/Users/avp/src/cc/hashcode $ gcc -O3 bloloops.c c:/Users/avp/src/cc/hashcode $ date; ./a; date Mon Aug 13 23:55:42 2012 six loops 6.170000e+017 3.617000e+018 5.617000e+018 5.561700e+019 2.561700e+019 1.061700e+019 Mon Aug 13 23:56:00 2012 c:/Users/avp/src/cc/hashcode $ date; ./a 1; date Mon Aug 13 23:56:17 2012 one loop 6.170000e+017 3.617000e+018 5.617000e+018 5.561700e+019 2.561700e+019 1.061700e+019 Mon Aug 13 23:56:23 2012 c:/Users/avp/src/cc/hashcode $ Все желающие приглашаются к экспериментированию (вместо теоретизирования на основе прочитанной литературы) с последующим обсуждением результатов. UPDATE Для замера времени исполнения фрагментов программы удобно использовать функцию: /* avp
время в миллисекундах */
#include #include
long long mtime() { struct timeval t;
gettimeofday(&t, NULL); long long mt = (long long)t.tv_sec * 1000 + t.tv_usec / 1000; return mt; } Меряем так: ... long long mtime(void); ... long long start = mtime(); // измеряемый код ... printf ("duration: %lld msec
",mtime()-start); ...

Комментариев нет:

Отправить комментарий