Объявление переменных за циклом или внутри цикла? - страница 5

 
pivalexander:

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

Для переменных, требуемых лишь в одном месте - да, вполне разумно объявить их перед самим этим блоком, особенно, когда блок небольшой. Но, если блок достаточно объемный, и переменные требуются еще где-то - то я бы предпочел объявлять из вначале функции.  Тут все-таки надо исходить из здравого смысла.

 
pivalexander:

Результат выполнения с пустым телом цикла, сильно отличается, гораздо быстрее работает

Test1, время выполнения: 0.548275 сек.
Test2, Время выполнения: 0.313978 сек.

а Вы что меряете в микросекундах? .... Вы уверены, что тест у Вас соответствует реальности?

;)

вот еще так протестировал:

#define N 8

#define   test(M,S,EX,res) {                             \
uint mss=GetTickCount();                                 \
ulong nn=(ulong)pow(10,M);                               \
for(ulong tst=0;tst<nn && !_StopFlag;tst++) \
{ EX;  res }                                             \
printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   string result;
   string s1;  test(N,"1. s1=",s1=(string)tst, result = s1;);
   string s2;  test(N,"2. s2=",s2=(string)tst, result = s2;);
   string s3;  test(N,"3. s3=",s3=(string)tst, result = s3;);
   string s4;  test(N,"4. s4=",s4=(string)tst, result = s4;);
   string s5;  test(N,"5. s5=",s5=(string)tst, result = s5;);

   test(N,"1. q=",string q=(string)tst, result = q;);
   test(N,"2. w=",string w=(string)tst, result = w;);
   test(N,"3. e=",string e=(string)tst, result = e;);
   test(N,"4. r=",string r=(string)tst, result = r;);
   test(N,"5. t=",string t=(string)tst, result = t;);
  }

2019.08.18 12:14:20.765 SpeedTest (EURUSD,H1) 1. s1=: loops=100000000 ms=8156

2019.08.18 12:14:29.127 SpeedTest (EURUSD,H1) 2. s2=: loops=100000000 ms=8359

2019.08.18 12:14:37.353 SpeedTest (EURUSD,H1) 3. s3=: loops=100000000 ms=8235

2019.08.18 12:14:45.464 SpeedTest (EURUSD,H1) 4. s4=: loops=100000000 ms=8109

2019.08.18 12:14:53.557 SpeedTest (EURUSD,H1) 5. s5=: loops=100000000 ms=8094

2019.08.18 12:15:01.446 SpeedTest (EURUSD,H1) 1. q=: loops=100000000 ms=7890

2019.08.18 12:15:09.159 SpeedTest (EURUSD,H1) 2. w=: loops=100000000 ms=7703

2019.08.18 12:15:16.903 SpeedTest (EURUSD,H1) 3. e=: loops=100000000 ms=7750

2019.08.18 12:15:24.716 SpeedTest (EURUSD,H1) 4. r=: loops=100000000 ms=7813

2019.08.18 12:15:32.661 SpeedTest (EURUSD,H1) 5. t=: loops=100000000 ms=7937

 
Igor Makanu:

а Вы что меряете в микросекундах? .... Вы уверены, что тест у Вас соответствует реальности?

   ulong  time_finish = GetMicrosecondCount();
   ulong  res = time_finish - time_start;

так замеряю

 
pivalexander:

так замеряю

это все понятно, но нужно хотя бы несколько секунд замерять 

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

имхо, тест хотя бы секунд 5 - это уже хоть какая достоверная инфа

 
Igor Makanu:

это все понятно, но нужно хотя бы несколько секунд замерять

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

имхо, тест хотя бы секунд 5 - это уже хоть какая достоверная инфа

Делал замеры по несколько секунд, результат одинаковый, зачем ждать долго, что бы сюда запостить результат 

 

В общем решил таки и я сделать тест, но 100% корректный, чтоб точно ничего не вырезалось  Вот такой вариант.

void OnStart()
{
  int count= (int)10e6;

  { 
    uint t= GetTickCount();
    int sum=0;
        
    for (int i=0; i<count; i++)
    {
       string st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test1, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
  
  {
    uint t = GetTickCount();
    int sum=0;
    string st = "";
    for (int i=0; i<count; i++)
    {
       st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test2, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
}

В режиме без оптимизации действительно второй вариант получается быстрее.  А вот с оптимизацией всё наоборот. Причём второй вариант почему-то становится медленней, чем был до оптимизации )

 
pivalexander:

Делал замеры по несколько секунд, результат одинаковый, зачем ждать долго, что бы сюда запостить результат 

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

дело Ваше, я как и писал Выше, не верю никому, даже Винде, процессору и себе ;)


Alexey Navoykov:

В общем решил таки и я сделать тест, но 100% корректный, чтоб точно ничего не вырезалось  Вот такой вариант.

В режиме без оптимизации действительно второй вариант получается быстрее.  А вот с оптимизацией всё наоборот. Причём второй вариант почему-то становится медленней, чем был до оптимизации )

не факт, нет srand() , я же писал, что rand() компилятор очень круто оптит ;)

и текст скрипта скопируйте раза 2 хотя бы - чтобы было видно если что заоптил компилятор ;)

 
pivalexander:

Причем тут память и процессор, речь про оптимизацию, теоретик вы книжный)

Если Вы продвинетесь дальше скобок своих рассуждений и поймете как работает компилятор и как работает его оптимизация, то Вам станет ясно, что любой компилятор преследует своей целью сократить количество тактов на выполнение кода и максимально сократить непоследовательное обращение к памяти, соответственно результат работы оптимизации любого компилятора, если она там есть, будет вам известен заранее, без дибильных тестов. Это все равно, что тестами определять, что 2 + 2 = 4... 

И на счет книжного теоретика... Этот теоретик занимается написанием с 87 года начиная с ЕС1020 и ZX Spectrum, написал не один свой компилятор и принял на работу к себе в компанию более 600 программистов...

 
Aleksandr Matveev:

Если Вы продвинетесь дальше скобок своих рассуждений и поймете как работает компилятор и как работает его оптимизация, то Вам станет ясно, что любой компилятор преследует своей целью сократить количество тактов на выполнение кода и максимально сократить непоследовательное обращение к памяти, соответственно результат работы оптимизации любого компилятора, если она там есть, будет вам известен заранее, без дибильных тестов. Это все равно, что тестами определять, что 2 + 2 = 4... 

И на счет книжного теоретика... Этот теоретик занимается написанием с 87 года начиная с ЕС1020 и ZX Spectrum, написал не один свой компилятор и принял на работу к себе в компанию более 600 программистов...

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

 
А знаете ли вы: что у стринга может быть небольшой внутренний буфер и при небольших строках данные могут целиком попадать туда? Так сказать для ускорения в большинстве тривиальных случаях. Пока возился с отловом malloc(), заметил, что если строка короче символов около 15, то malloc вообще не дёргается. Как бы ваши тесты ...