Циклы 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); // Постоянно вычисляется PI
}

// После оптимизации
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 разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Умный дом 1. Постановка задачи.

Умный дом 1. Постановка задачи.

Умный дом 1. Постановка задачи. Каждый человек представляет себе свой умный дом в соответствии со с..

Модуль гальваноразвязки 4-канальный

Модуль гальваноразвязки 4-канальный

Модуль защиты и гальванической развязки 4-х дискретных входов контроллера с винтовыми клеммниками. ..

114.76грн.

Драйвер шагового двигателя RAMPS 1.4 для CNC или 3D-принтера

Драйвер шагового двигателя RAMPS 1.4 для CNC или 3D-принтера

Драйвер A4988 под CNC-шилд RAMPS 1.4Есть возможность настраивать рабочий ток двигателя при помо..

60.91грн.

Шилд SHT30 для Wemos D1 mini

Шилд SHT30 для Wemos D1 mini

Шилд датчика температуры и влажности на основе SHT30Коммуникационный интерфейс I2CДиапазон измерения..

102.48грн.

Использование внутреннего Watchdog таймера в ESP32

Использование внутреннего Watchdog таймера в ESP32

Использование внутреннего Watchdog таймера в ESP32 Watchdog (WDT) — это встроенный таймер микроко..