Цикли 8 — Оптимізація циклів

Вступ

Оптимізація циклів в Arduino особливо важлива, коли потрібно обробляти великі масиви даних, швидко реагувати на зовнішні події або працювати з високочастотними сигналами. Навіть незначне зменшення кількості операцій у циклі може суттєво прискорити виконання програми та зменшити навантаження на мікроконтролер.

Мінімізація кількості ітерацій

Якщо заздалегідь відомо, що пошук у масиві чи наборі даних можна завершити раніше, варто скористатися оператором break. Це скорочує час виконання та вивільняє ресурси для інших завдань.


// Пошук першого значення більше 100
for (int i = 0; i < 1000; i++) {
  if (data[i] > 100) {
    break; // Далі шукати не потрібно
  }
}
  

Попередні обчислення

Обчислення всередині циклу, які не залежать від індексу, варто винести за його межі. Це зменшить кількість повторюваних операцій і прискорить виконання.


// До оптимізації
for (int i = 0; i < 100; i++) {
  float val = sin(3.14159 * i / 180);
}

// Після оптимізації
float factor = 3.14159 / 180;
for (int i = 0; i < 100; i++) {
  float val = sin(factor * i);
}
  

Робота з масивами та вказівниками

Перебір масиву за допомогою вказівників іноді може бути швидшим, ніж за індексом, особливо в великих масивах. Але такий підхід вимагає обережності, щоб уникнути виходу за межі масиву.


int arr[5] = {10, 20, 30, 40, 50};

// Перебір за індексом
for (int i = 0; i < 5; i++) {
  Serial.println(arr[i]);
}

// Перебір за вказівником
for (int *ptr = arr; ptr < arr + 5; ptr++) {
  Serial.println(*ptr);
}
  

Практика: Порівняння швидкості перебору масиву


int arr[1000];
unsigned long startTime, endTime;

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 1000; i++) arr[i] = i;

  // За індексом
  startTime = micros();
  long sum1 = 0;
  for (int i = 0; i < 1000; i++) {
    sum1 += arr[i];
  }
  endTime = micros();
  Serial.print("За індексом: ");
  Serial.print(endTime - startTime);
  Serial.println(" мкс");

  // За вказівником
  startTime = micros();
  long sum2 = 0;
  for (int *p = arr; p < arr + 1000; p++) {
    sum2 += *p;
  }
  endTime = micros();
  Serial.print("За вказівником: ");
  Serial.print(endTime - startTime);
  Serial.println(" мкс");
}

void loop() {
}
  

Проєкт: «Високошвидкісний лічильник подій»

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


const byte inputPin = 2;
volatile unsigned long pulseCount = 0;
unsigned long prevMillis = 0;
const unsigned long interval = 1000; // 1 секунда

void IRAM_ATTR countPulse() {
  pulseCount++;
}

void setup() {
  Serial.begin(115200);
  pinMode(inputPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(inputPin), countPulse, RISING);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - prevMillis >= interval) {
    prevMillis = currentMillis;
    Serial.print("Подій за секунду: ");
    Serial.println(pulseCount);
    pulseCount = 0;
  }
}
  

Висновок

Оптимізація циклів — важливий навик у роботі з Arduino, особливо коли потрібна висока швидкість реакції. Використовуючи мінімізацію ітерацій, попередні обчислення та ефективну роботу з масивами, можна суттєво підвищити продуктивність проєктів.

<< Проекти << Усі товари >> Статті, уроки >>

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
BMS плата захисту 3х літій-іонних акумуляторів 10А

BMS плата захисту 3х літій-іонних акумуляторів 10А

Модуль захисту батареї трьох літій-іонних акумуляторівНапруга відсічення при заряді 4,25...4,35ВНапр..

114.46грн.

Припой з каніфоллю 0,5мм 30г

Припой з каніфоллю 0,5мм 30г

Нитка припою для тонкої пайки мілких радіодеталей, що містить флюсСвинця 40 %Олова 60 %Флюса 1,2 %На..

211.57грн.

ESP32 та Telegram bot: віддалений моніторинг

ESP32 та Telegram bot: віддалений моніторинг

ESP32 та Telegram bot: віддалений моніторинг Сучасні IoT-системи все частіше використовують хма..

Модуль реле 4-канальний 12В 10А

Модуль реле 4-канальний 12В 10А

4-канальный модуль реле для підключення напряму до дискретного виходу контролера. Світлодіодна індик..

159.74грн.

Ремінь зубчастий 6 мм для 3D-принтера

Ремінь зубчастий 6 мм для 3D-принтера

Відрізок зубчастого ременя шириною 6 мм.Застосовується для переміщення каретки 3D-принтера або CNC п..

49.26грн.