Оптимизация кода.

Dima85
Offline
Зарегистрирован: 07.01.2013

У меня достаточно большой скечь . Иногда Arduino сложно с ним справляться и она зависает.

Появилось несколько идей по разгрузки ее. Нужны ваши советы.

Что менее ресурсоемко для Arduino
1 вариант:
 

     if (LightSensor1 < 800 && LightSensor1 < LightSensor2+100 && LightSensor3 == 0) {
         
      }

2 вариант:

     if (LightSensor1 < 800 && LightSensor1) {
        if (LightSensor2+100) {
          if (LightSensor3 == 0) {
        
          }
        }
      }

Далее что лучше использовать:
byte LightSensor1;
или
int LightSensor1;

В переменной LightSensor1 хранится число от 0 до 30. byte насколько я понимаю будит менее энергоемко, но как-то я этого не почувствовал. Мне показалось с int arduino лучше работает.

 

Dima85
Offline
Зарегистрирован: 07.01.2013

Второй вариант с ошибкой, правильно так:

if (LightSensor1 < 800) {
	   if (LightSensor2+100) {
	     if (LightSensor3 == 0) {
	    
	     }
	   }
	 }

 

Далее:

Варианты

if (LightSensor1 < 800)

if (LightSensor1 == 800)

if (LightSensor1 <= 800)

Какой из них менее ресурсоемкий?

 

maksim
Offline
Зарегистрирован: 12.02.2012

В первом случае без разницы. Во втором читайте Программирование -> int и byte.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

максим мне лично так не кажется. хотя может и ошибаюсь. тут вопрос как выполняется программа. 

условие с несколькими параметрами

если не выполнилось 1 условие  и стоит && для остальных, то есть должны выполнится все, программа сразу пропустит после 1 несовпадения или все таки проверит каждое?

если каждое то лучше писать по отдельности если важна скорость

Dima85
Offline
Зарегистрирован: 07.01.2013

maksim, обоснуйте пожалуйста как-то первый случай.


if (LightSensor1 < 800) { // если это условие не соответствует arduino разве проверяет последующие условия в нем? Следовательно такой вариант должен быть лучше
	       if (LightSensor2+100) {
	         if (LightSensor3 == 0) {
	         
	         }
	       }
	     }

И хочется услышать что-то о:

Варианты

if (LightSensor1 < 800)

if (LightSensor1 == 800)

if (LightSensor1 <= 800)

Какой из них менее ресурсоемкий?

MaksMS
Offline
Зарегистрирован: 11.03.2013

Dima85 пишет:

 Иногда Arduino сложно с ним справляться и она зависает.

Ардуина может виснуть из-за проблем с питанием или когда память кончается обычно..(ну и некоторые могут умудриться отправить м/к в бесконечный цикл..)

Где возможно,то лучше использовать переменные byte ,а не int  .

Вообще без кода тут нечего отптимизировать

step962
Offline
Зарегистрирован: 23.05.2011

MaksMS пишет:

ну и некоторые могут умудриться отправить м/к в бесконечный цикл..

В бесконечный цикл умудряются отправить микроконтроллер все

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

axill
Offline
Зарегистрирован: 05.09.2011

Dima85 пишет:

У меня достаточно большой скечь . Иногда Arduino сложно с ним справляться и она зависает.

Появилось несколько идей по разгрузки ее. Нужны ваши советы.

Что менее ресурсоемко для Arduino
1 вариант:
 

     if (LightSensor1 < 800 && LightSensor1 < LightSensor2+100 && LightSensor3 == 0) {
         
      }

2 вариант:

     if (LightSensor1 < 800 && LightSensor1) {
        if (LightSensor2+100) {
          if (LightSensor3 == 0) {
        
          }
        }
      }

Далее что лучше использовать:
byte LightSensor1;
или
int LightSensor1;

В переменной LightSensor1 хранится число от 0 до 30. byte насколько я понимаю будит менее энергоемко, но как-то я этого не почувствовал. Мне показалось с int arduino лучше работает.

 

 

с точки зрения стабильности работы и отсутствия зависаний - без разницы

если виснет то по другой причине. Либо железо, либо грубые ошибки в программе. Часто встречаются такие ошибки:

- вылезазание за границы массива

- не корректное использование указателей

- отсутствие или ошибочное планирование заполнения оперативной памяти

maksim
Offline
Зарегистрирован: 12.02.2012

jeka_tm пишет:

если не выполнилось 1 условие  и стоит && для остальных, то есть должны выполнится все, программа сразу пропустит после 1 несовпадения или все таки проверит каждое?

void setup() 
{
  Serial.begin(9600);
  if(Check() > 3 && Check() == 5 && Check() < 7);
}

byte Check()
{
  static byte times = 0;
  times++;
  Serial.print(times);
  Serial.println(" CHECK");
  return 3;
}

void loop(){}

Поробуйте 

return 4;
return 5;

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Экономьте память, пишите 


 Serial.println( F ( " CHECK"));

 

maksim
Offline
Зарегистрирован: 12.02.2012

Dima85 пишет:

if (LightSensor1 < 800)

if (LightSensor1 == 800)

if (LightSensor1 <= 800)

Без разницы.

ites
Offline
Зарегистрирован: 26.12.2013

Dima85 пишет:

У меня достаточно большой скечь . Иногда Arduino сложно с ним справляться и она зависает.

Появилось несколько идей по разгрузки ее. Нужны ваши советы.

Что менее ресурсоемко для Arduino
1 вариант:
 

     if (LightSensor1 < 800 && LightSensor1 < LightSensor2+100 && LightSensor3 == 0) {
         
      }

2 вариант:

     if (LightSensor1 < 800 && LightSensor1) {
        if (LightSensor2+100) {
          if (LightSensor3 == 0) {
        
          }
        }
      }

Далее что лучше использовать:
byte LightSensor1;
или
int LightSensor1;

В переменной LightSensor1 хранится число от 0 до 30. byte насколько я понимаю будит менее энергоемко, но как-то я этого не почувствовал. Мне показалось с int arduino лучше работает.

 

1. Второй исправленный вариант полностью эквивалентен первому. Операция && вычисляет аргументы слева направо до первого ложного.

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

3. Если программа зависает, то проблема "где-то ещё", точно не в том как записывается условие и вряд ли в переходе от int к byte.

axill
Offline
Зарегистрирован: 05.09.2011

всякие String и даже обычные строковые константы очень прожорливы к оперативной памяти... да да именно оперативной

если не использовать PROGMEM то все строковые константы перед запуском setup() грузятся из флэш в оперативную память и используются оттуда и живут там до скончания века

ites
Offline
Зарегистрирован: 26.12.2013

axill пишет:

всякие String и даже обычные строковые константы очень прожорливы к оперативной памяти... да да именно оперативной

если не использовать PROGMEM то все строковые константы перед запуском setup() грузятся из флэш в оперативную память и используются оттуда и живут там до скончания века

Да, именно константные строки стоит в прогмем пихать, согласен. Хотя доступ туда не так чтобы сильно удобен.

Dima85
Offline
Зарегистрирован: 07.01.2013

trembo пишет:

Экономьте память, пишите 


 Serial.println( F ( " CHECK"));

 

 

Всем большое спасибо. Расскажите пожалуйста подробней о коде предложенный trembo, что делает символ "F"?

ites
Offline
Зарегистрирован: 26.12.2013

Dima85 пишет:

trembo пишет:

Экономьте память, пишите 


 Serial.println( F ( " CHECK"));

 

 

Всем большое спасибо. Расскажите пожалуйста подробней о коде предложенный trembo, что делает символ "F"?

Символ F (макрос такой) делает две вещи:

1. строковая константа помещается в програмную область, которой обычно больше, чем SRAM;

2. тип получаемого значения становится "ни на что непохожим", чтобы случайно не спутать это с нормальным указателем в память.

Метод Serial.println умеет работать с таким типом данных, он знает как правильно читать из програмной памяти.